From ab2b67c21ebeee306e0635444296402d6d5e43d7 Mon Sep 17 00:00:00 2001 From: manongjohn <19245851+manongjohn@users.noreply.github.com> Date: Fri, 29 Sep 2023 13:58:37 -0400 Subject: [PATCH] Render To Folders --- toonz/sources/include/tfarmtask.h | 11 ++-- .../include/toonz/multimediarenderer.h | 4 +- toonz/sources/include/toutputproperties.h | 6 ++ toonz/sources/tcomposer/tcomposer.cpp | 11 +++- toonz/sources/toonz/batches.cpp | 4 +- toonz/sources/toonz/outputsettingspopup.cpp | 24 ++++++- toonz/sources/toonz/outputsettingspopup.h | 2 + toonz/sources/toonz/rendercommand.cpp | 13 ++-- toonz/sources/toonz/tasksviewer.cpp | 30 +++++++++ toonz/sources/toonz/tasksviewer.h | 2 + toonz/sources/toonzfarm/tfarm/tfarmtask.cpp | 43 ++++++++----- toonz/sources/toonzlib/multimediarenderer.cpp | 62 +++++++++++++++---- toonz/sources/toonzlib/outputproperties.cpp | 5 +- toonz/sources/toonzlib/sceneproperties.cpp | 12 +++- 14 files changed, 183 insertions(+), 46 deletions(-) diff --git a/toonz/sources/include/tfarmtask.h b/toonz/sources/include/tfarmtask.h index 5ed368bd..0dc8cc89 100644 --- a/toonz/sources/include/tfarmtask.h +++ b/toonz/sources/include/tfarmtask.h @@ -98,6 +98,7 @@ public: int m_multimedia; bool m_renderKeysOnly; + bool m_renderToFolders; int m_threadsIndex; int m_maxTileSizeIndex; @@ -120,9 +121,9 @@ public: const QString &user, const QString &host, int stepCount, int priority, const TFilePath &taskFilePath, const TFilePath &outputPath, int from, int to, int step, int shrink, - int multimedia, bool renderKeysOnly, int chunksize, - int threadsIndex, int maxTileSizeIndex, OverwriteBehavior overwrite, - bool onlyvisible); + int multimedia, bool renderKeysOnly, bool renderToFolders, + int chunksize, int threadsIndex, int maxTileSizeIndex, + OverwriteBehavior overwrite, bool onlyvisible); virtual ~TFarmTask() { delete m_dependencies; } @@ -157,8 +158,8 @@ public: const QString &host, int stepCount, int priority, const TFilePath &taskFilePath, const TFilePath &outputPath, int from, int to, int step, int shrink, int multimedia, - bool renderKeysOnly, int chunksize, int threadsIndex, - int maxTileSizeIndex); + bool renderKeysOnly, bool renderToFolders, int chunksize, + int threadsIndex, int maxTileSizeIndex); TFarmTaskGroup(const QString &id, const QString &name, const QString &user, const QString &host, int stepCount, int priority, diff --git a/toonz/sources/include/toonz/multimediarenderer.h b/toonz/sources/include/toonz/multimediarenderer.h index b88f1b07..9f7bb619 100644 --- a/toonz/sources/include/toonz/multimediarenderer.h +++ b/toonz/sources/include/toonz/multimediarenderer.h @@ -68,7 +68,8 @@ public: MultimediaRenderer(ToonzScene *scene, const TFilePath &moviePath, int multimediaMode, bool renderKeysOnly, - int threadCount = 1, bool cacheResults = true); + bool renderToFolders, int threadCount = 1, + bool cacheResults = true); ~MultimediaRenderer(); @@ -85,6 +86,7 @@ public: enum { COLUMNS = 1, LAYERS = 2 }; int getMultimediaMode() const; bool isRenderKeysOnly() const; + bool isRenderToFolders() const; //! Returns the currently active TRenderer. TRenderer *getTRenderer(); diff --git a/toonz/sources/include/toutputproperties.h b/toonz/sources/include/toutputproperties.h index 1b8b57e5..54a9c923 100644 --- a/toonz/sources/include/toutputproperties.h +++ b/toonz/sources/include/toutputproperties.h @@ -87,6 +87,7 @@ private: int m_multimediaRendering; bool m_renderKeysOnly; + bool m_renderToFolders; int m_maxTileSizeIndex; int m_threadIndex; @@ -215,6 +216,11 @@ Insert in \b v all extension in format properties of output settings. void setRenderKeysOnly(bool keysOnly) { m_renderKeysOnly = keysOnly; } bool isRenderKeysOnly() const { return m_renderKeysOnly; } + void setRenderToFolders(bool renderToFolders) { + m_renderToFolders = renderToFolders; + } + bool isRenderToFolders() const { return m_renderToFolders; } + /*! Sets the granularity of raster allocations for rendering processes. The specified value refers to an index associated with const values, spanning from 0 (no bound, ie giant rasters are allowed) to 3 (highly diff --git a/toonz/sources/tcomposer/tcomposer.cpp b/toonz/sources/tcomposer/tcomposer.cpp index 05538b63..2a6c2cc9 100644 --- a/toonz/sources/tcomposer/tcomposer.cpp +++ b/toonz/sources/tcomposer/tcomposer.cpp @@ -487,6 +487,7 @@ static std::pair generateMovie(ToonzScene *scene, const TFilePath &fp, int multimediaRender = outputSettings.getMultimediaRendering(); bool renderKeysOnly = outputSettings.isRenderKeysOnly(); + bool renderToFolders = outputSettings.isRenderToFolders(); //--------------------------------------------------------- // Multimedia render @@ -494,7 +495,8 @@ static std::pair generateMovie(ToonzScene *scene, const TFilePath &fp, if (multimediaRender) { MultimediaRenderer multimediaRenderer(scene, fp, multimediaRender, - renderKeysOnly, threadCount); + renderKeysOnly, renderToFolders, + threadCount); TRenderSettings rs = outputSettings.getRenderSettings(); rs.m_maxTileSize = maxTileSize; rs.m_shrinkX = rs.m_shrinkY = shrink; @@ -610,6 +612,7 @@ int main(int argc, char *argv[]) { IntQualifier shrinkOpt("-shrink n", "Shrink"); IntQualifier multimedia("-multimedia n", "Multimedia rendering mode"); IntQualifier renderKeysOnly("-renderkeysonly n", "Render keys drawings only"); + IntQualifier renderToFolders("-rendertofolders n", "Render To Folders"); StringQualifier farmData("-farm data", "TFarm Controller"); StringQualifier idq("-id n", "id"); StringQualifier nthreads("-nthreads n", "Number of rendering threads"); @@ -617,7 +620,8 @@ int main(int argc, char *argv[]) { "Enable tile rendering of max n MB per tile"); StringQualifier tmsg("-tmsg val", "only internal use"); usageLine = srcName + dstName + range + stepOpt + shrinkOpt + multimedia + - renderKeysOnly + farmData + idq + nthreads + tileSize + tmsg; + renderKeysOnly + renderToFolders + farmData + idq + nthreads + + tileSize + tmsg; // system path qualifiers std::map>> @@ -932,6 +936,9 @@ int main(int argc, char *argv[]) { if (renderKeysOnly.isSelected()) scene->getProperties()->getOutputProperties()->setRenderKeysOnly( renderKeysOnly.getValue()); + if (renderToFolders.isSelected()) + scene->getProperties()->getOutputProperties()->setRenderToFolders( + renderToFolders.getValue()); // Retrieve Thread count const int procCount = TSystem::getProcessorCount(); diff --git a/toonz/sources/toonz/batches.cpp b/toonz/sources/toonz/batches.cpp index 2ec2b63b..7f058c2d 100644 --- a/toonz/sources/toonz/batches.cpp +++ b/toonz/sources/toonz/batches.cpp @@ -361,6 +361,7 @@ void BatchesController::addComposerTask(const TFilePath &_taskFilePath) { int multimedia = out.getMultimediaRendering(); bool renderKeysOnly = out.isRenderKeysOnly(); + bool renderToFolders = out.isRenderToFolders(); int threadsIndex = out.getThreadIndex(); int maxTileSizeIndex = out.getMaxTileSizeIndex(); @@ -386,7 +387,8 @@ void BatchesController::addComposerTask(const TFilePath &_taskFilePath) { TFarmTaskGroup *taskGroup = new TFarmTaskGroup( id, name, TSystem::getUserName(), TSystem::getHostName(), sceneFrameCount, 50, taskFilePath, outputPath, r0, r1, step, shrink, multimedia, - renderKeysOnly, taskChunkSize, threadsIndex, maxTileSizeIndex); + renderKeysOnly, renderToFolders, taskChunkSize, threadsIndex, + maxTileSizeIndex); try { BatchesController::instance()->addTask(id, taskGroup); diff --git a/toonz/sources/toonz/outputsettingspopup.cpp b/toonz/sources/toonz/outputsettingspopup.cpp index d5041e54..2b0301a7 100644 --- a/toonz/sources/toonz/outputsettingspopup.cpp +++ b/toonz/sources/toonz/outputsettingspopup.cpp @@ -941,6 +941,9 @@ QFrame *OutputSettingsPopup::createMoreSettingsBox() { m_renderKeysOnly = new DVGui::CheckBox(tr("Render Key Drawings Only"), this); m_renderKeysOnly->setEnabled(false); + m_renderToFolders = new DVGui::CheckBox(tr("Render To Folders"), this); + m_renderToFolders->setEnabled(false); + //----- QGridLayout *lay = new QGridLayout(); @@ -983,9 +986,11 @@ QFrame *OutputSettingsPopup::createMoreSettingsBox() { Qt::AlignLeft | Qt::AlignVCenter); lay->addWidget(m_renderKeysOnly, 6, 1, 1, 3, Qt::AlignLeft | Qt::AlignVCenter); + lay->addWidget(m_renderToFolders, 7, 1, 1, 3, + Qt::AlignLeft | Qt::AlignVCenter); - lay->addWidget(m_doStereoscopy, 7, 0); - lay->addWidget(new QLabel(tr("Camera Shift:")), 7, 1, 1, 2, + lay->addWidget(m_doStereoscopy, 8, 0); + lay->addWidget(new QLabel(tr("Camera Shift:")), 8, 1, 1, 2, Qt::AlignRight | Qt::AlignVCenter); lay->addWidget(m_stereoShift, 8, 3, Qt::AlignLeft | Qt::AlignVCenter); } @@ -1020,6 +1025,8 @@ QFrame *OutputSettingsPopup::createMoreSettingsBox() { SLOT(onStereoChanged())); ret = ret && connect(m_renderKeysOnly, SIGNAL(stateChanged(int)), this, SLOT(onRenderKeysOnlyChecked(int))); + ret = ret && connect(m_renderToFolders, SIGNAL(stateChanged(int)), this, + SLOT(onRenderToFoldersChecked(int))); assert(ret); return moreSettingsBox; } @@ -1173,7 +1180,9 @@ void OutputSettingsPopup::updateField() { m_fileFormat->findText(QString::fromStdString(path.getType()))); m_multimediaOm->setCurrentIndex(prop->getMultimediaRendering()); m_renderKeysOnly->setChecked(prop->isRenderKeysOnly()); + m_renderToFolders->setChecked(prop->isRenderToFolders()); m_renderKeysOnly->setEnabled(prop->getMultimediaRendering()); + m_renderToFolders->setEnabled(prop->getMultimediaRendering()); } // Refresh format if allow-multithread was toggled @@ -1841,6 +1850,7 @@ void OutputSettingsPopup::onMultimediaChanged(int state) { prop->setMultimediaRendering(state); m_renderKeysOnly->setEnabled(state); + m_renderToFolders->setEnabled(state); TApp::instance()->getCurrentScene()->setDirtyFlag(true); } @@ -1857,6 +1867,16 @@ void OutputSettingsPopup::onRenderKeysOnlyChecked(int) { //----------------------------------------------------------------------------- +void OutputSettingsPopup::onRenderToFoldersChecked(int) { + if (!getCurrentScene()) return; + TOutputProperties *prop = getProperties(); + prop->setRenderToFolders(m_renderToFolders->isChecked()); + + TApp::instance()->getCurrentScene()->setDirtyFlag(true); +} + +//----------------------------------------------------------------------------- + void OutputSettingsPopup::onThreadsComboChanged(int type) { if (!getCurrentScene()) return; TOutputProperties *prop = getProperties(); diff --git a/toonz/sources/toonz/outputsettingspopup.h b/toonz/sources/toonz/outputsettingspopup.h index 4b73dc0d..cffc875a 100644 --- a/toonz/sources/toonz/outputsettingspopup.h +++ b/toonz/sources/toonz/outputsettingspopup.h @@ -71,6 +71,7 @@ class OutputSettingsPopup : public DVGui::Dialog { QComboBox *m_threadsComboOm; bool m_allowMT; DVGui::CheckBox *m_renderKeysOnly; + DVGui::CheckBox *m_renderToFolders; DVGui::DoubleLineEdit *m_frameRateFld; QPushButton *m_fileFormatButton; @@ -133,6 +134,7 @@ protected slots: void onSubcameraChecked(int state); void onMultimediaChanged(int mode); void onRenderKeysOnlyChecked(int); + void onRenderToFoldersChecked(int); void onThreadsComboChanged(int type); void onRasterGranularityChanged(int type); void onStereoChecked(int); diff --git a/toonz/sources/toonz/rendercommand.cpp b/toonz/sources/toonz/rendercommand.cpp index 33f6b7b8..e46a8f98 100644 --- a/toonz/sources/toonz/rendercommand.cpp +++ b/toonz/sources/toonz/rendercommand.cpp @@ -163,6 +163,7 @@ class RenderCommand { int m_multimediaRender; bool m_renderKeysOnly; + bool m_renderToFolders; public: RenderCommand() @@ -175,7 +176,8 @@ public: , m_oldCameraRes(0, 0) , m_timeStretchFactor(1) , m_multimediaRender(0) - , m_renderKeysOnly(false) { + , m_renderKeysOnly(false) + , m_renderToFolders(false) { setCommandHandler("MI_Render", this, &RenderCommand::onRender); setCommandHandler("MI_SaveAndRender", this, &RenderCommand::onSaveAndRender); setCommandHandler("MI_FastRender", this, &RenderCommand::onFastRender); @@ -241,6 +243,7 @@ sprop->getOutputProperties()->setRenderSettings(rso);*/ m_stepd = m_step; m_multimediaRender = 0; m_renderKeysOnly = false; + m_renderToFolders = false; return true; } @@ -306,6 +309,7 @@ sprop->getOutputProperties()->setRenderSettings(rso);*/ // Update the multimedia render switch m_multimediaRender = outputSettings.getMultimediaRendering(); m_renderKeysOnly = outputSettings.isRenderKeysOnly(); + m_renderToFolders = outputSettings.isRenderToFolders(); return true; } @@ -735,10 +739,11 @@ void RenderCommand::multimediaRender() { TRenderSettings rs = prop->getRenderSettings(); rs.m_maxTileSize = maxTileSizes[index]; - int multimedia = prop->getMultimediaRendering(); - bool renderKeysOnly = prop->isRenderKeysOnly(); + int multimedia = prop->getMultimediaRendering(); + bool renderKeysOnly = prop->isRenderKeysOnly(); + bool renderToFolders = prop->isRenderToFolders(); MultimediaRenderer multimediaRenderer(scene, m_fp, multimedia, renderKeysOnly, - threadCount); + renderToFolders, threadCount); multimediaRenderer.setRenderSettings(rs); TPointD cameraDpi = scene->getCurrentCamera()->getDpi(); diff --git a/toonz/sources/toonz/tasksviewer.cpp b/toonz/sources/toonz/tasksviewer.cpp index 95573a12..d2a83979 100644 --- a/toonz/sources/toonz/tasksviewer.cpp +++ b/toonz/sources/toonz/tasksviewer.cpp @@ -341,7 +341,9 @@ void TaskSheet::update(TFarmTask *task) { m_shrink->setText(QString::number(task->m_shrink)); m_multimedia->setCurrentIndex(task->m_multimedia); m_renderKeysOnly->setChecked(task->m_renderKeysOnly); + m_renderToFolders->setChecked(task->m_renderToFolders); m_renderKeysOnly->setEnabled(m_multimedia->currentIndex()); + m_renderToFolders->setEnabled(m_multimedia->currentIndex()); m_threadsCombo->setCurrentIndex(task->m_threadsIndex); m_rasterGranularityCombo->setCurrentIndex(task->m_maxTileSizeIndex); @@ -695,6 +697,7 @@ void TaskSheet::setMultimedia(int) { } m_renderKeysOnly->setEnabled(m_multimedia->currentIndex()); + m_renderToFolders->setEnabled(m_multimedia->currentIndex()); m_viewer->startTimer(); } @@ -723,6 +726,28 @@ void TaskSheet::setRenderKeysOnly(int) { //----------------------------------------------------------------------------- +void TaskSheet::setRenderToFolders(int) { + if (!m_task) return; + if (m_task->m_renderToFolders == + (m_renderToFolders->checkState() == Qt::Checked)) + return; + + m_task->m_renderToFolders = (m_renderToFolders->checkState() == Qt::Checked); + m_commandLine->setText(m_task->getCommandLine()); + BatchesController::instance()->setDirtyFlag(true); + + // Update children tasks, if present. + TFarmTaskGroup *taskGroup = dynamic_cast(m_task); + if (taskGroup) { + for (int i = 0; i < taskGroup->getTaskCount(); ++i) + taskGroup->getTask(i)->m_renderToFolders = taskGroup->m_renderToFolders; + } + + m_viewer->startTimer(); +} + +//----------------------------------------------------------------------------- + void TaskSheet::setThreadsCombo(int) { if (!m_task) return; if (m_task->m_threadsIndex == m_threadsCombo->currentIndex()) return; @@ -873,6 +898,8 @@ TaskSheet::TaskSheet(TasksViewer *owner) : QScrollArea(owner) { Qt::AlignLeft | Qt::AlignTop, row1++); ::create(m_renderKeysOnly, layout1, tr("Render Key Drawings Only"), row1++, 4); + ::create(m_renderToFolders, layout1, tr("Render To Folders"), row1++, + 4); ::create(m_from, m_to, layout1, tr("From:"), tr("To:"), Qt::AlignRight | Qt::AlignTop, Qt::AlignRight | Qt::AlignTop, row1++); @@ -887,6 +914,7 @@ TaskSheet::TaskSheet(TasksViewer *owner) : QScrollArea(owner) { m_multimedia->addItems(multimediaTypes); m_renderKeysOnly->setEnabled(false); + m_renderToFolders->setEnabled(false); ::create(m_threadsCombo, layout1, tr("Dedicated CPUs:"), row1++, 3); QStringList threadsTypes; @@ -985,6 +1013,8 @@ TaskSheet::TaskSheet(TasksViewer *owner) : QScrollArea(owner) { SLOT(setMultimedia(int))); ret = ret && connect(m_renderKeysOnly, SIGNAL(stateChanged(int)), this, SLOT(setRenderKeysOnly(int))); + ret = ret && connect(m_renderToFolders, SIGNAL(stateChanged(int)), this, + SLOT(setRenderToFolders(int))); ret = ret && connect(m_visible, SIGNAL(stateChanged(int)), this, SLOT(setVisible(int))); diff --git a/toonz/sources/toonz/tasksviewer.h b/toonz/sources/toonz/tasksviewer.h index 2bb0cf4b..bb65d04e 100644 --- a/toonz/sources/toonz/tasksviewer.h +++ b/toonz/sources/toonz/tasksviewer.h @@ -127,6 +127,7 @@ class TaskSheet final : public QScrollArea { QListWidget *m_notAddedBox; DVGui::CheckBox *m_visible; DVGui::CheckBox *m_renderKeysOnly; + DVGui::CheckBox *m_renderToFolders; QComboBox *m_overwrite; QComboBox *m_multimedia; QComboBox *m_threadsCombo; @@ -150,6 +151,7 @@ protected slots: void setOverwrite(int); void setMultimedia(int); void setRenderKeysOnly(int); + void setRenderToFolders(int); void setThreadsCombo(int); void setGranularityCombo(int); void setPriority(); diff --git a/toonz/sources/toonzfarm/tfarm/tfarmtask.cpp b/toonz/sources/toonzfarm/tfarm/tfarmtask.cpp index 0bd6b564..2cdf1e42 100644 --- a/toonz/sources/toonzfarm/tfarm/tfarmtask.cpp +++ b/toonz/sources/toonzfarm/tfarm/tfarmtask.cpp @@ -130,6 +130,7 @@ TFarmTask::TFarmTask(const QString &name) , m_chunkSize(-1) , m_multimedia(0) // Full render, no multimedia , m_renderKeysOnly(false) + , m_renderToFolders(false) , m_threadsIndex(2) // All threads , m_maxTileSizeIndex(0) // No tiling , m_overwrite() @@ -144,8 +145,9 @@ TFarmTask::TFarmTask(const QString &id, const QString &name, bool composerTask, int priority, const TFilePath &taskFilePath, const TFilePath &outputPath, int from, int to, int step, int shrink, int multimedia, bool renderKeysOnly, - int chunksize, int threadsIndex, int maxTileSizeIndex, - OverwriteBehavior overwrite, bool onlyvisible) + bool renderToFolders, int chunksize, int threadsIndex, + int maxTileSizeIndex, OverwriteBehavior overwrite, + bool onlyvisible) : m_isComposerTask(composerTask) , m_id(id) @@ -166,6 +168,7 @@ TFarmTask::TFarmTask(const QString &id, const QString &name, bool composerTask, , m_shrink(shrink) , m_multimedia(multimedia) , m_renderKeysOnly(renderKeysOnly) + , m_renderToFolders(renderToFolders) , m_threadsIndex(threadsIndex) , m_maxTileSizeIndex(maxTileSizeIndex) , m_chunkSize(chunksize) @@ -224,6 +227,7 @@ TFarmTask &TFarmTask::operator=(const TFarmTask &rhs) { m_overwrite = rhs.m_overwrite; m_multimedia = rhs.m_multimedia; m_renderKeysOnly = rhs.m_renderKeysOnly; + m_renderToFolders = rhs.m_renderToFolders; m_threadsIndex = rhs.m_threadsIndex; m_maxTileSizeIndex = rhs.m_maxTileSizeIndex; m_chunkSize = rhs.m_chunkSize; @@ -266,6 +270,7 @@ bool TFarmTask::operator==(const TFarmTask &task) { task.m_shrink == m_shrink && task.m_onlyVisible == m_onlyVisible && task.m_overwrite == m_overwrite && task.m_multimedia == m_multimedia && task.m_renderKeysOnly == m_renderKeysOnly && + task.m_renderToFolders == m_renderToFolders && task.m_threadsIndex == m_threadsIndex && task.m_maxTileSizeIndex == m_maxTileSizeIndex && task.m_chunkSize == m_chunkSize && equalDependencies); @@ -449,6 +454,9 @@ void TFarmTask::parseCommandLine(QString commandLine) { } else if (l.at(i) == "-renderkeysonly") { m_renderKeysOnly = (l.at(i + 1).toInt()); i += 2; + } else if (l.at(i) == "-rendertofolders") { + m_renderToFolders = (l.at(i + 1).toInt()); + i += 2; } else if (l.at(i) == "-nthreads") { QString str(l.at(i + 1)); @@ -534,6 +542,7 @@ QString TFarmTask::getCommandLineArguments() const { cmdline += " -shrink " + QString::number(m_shrink); cmdline += " -multimedia " + QString::number(m_multimedia); cmdline += " -renderkeysonly " + QString::number(m_renderKeysOnly ? 1 : 0); + cmdline += " -rendertofolders " + QString::number(m_renderToFolders ? 1 : 0); const QString threadCounts[3] = {"single", "half", "all"}; cmdline += " -nthreads " + threadCounts[m_threadsIndex]; @@ -588,6 +597,7 @@ QStringList TFarmTask::getCommandLineArgumentsList() const { ret << "-shrink" << QString::number(m_shrink); ret << "-multimedia" << QString::number(m_multimedia); ret << "-renderkeysonly" << QString::number(m_renderKeysOnly ? 1 : 0); + ret << "-rendertofolders" << QString::number(m_renderToFolders ? 1 : 0); const QString threadCounts[3] = {"single", "half", "all"}; ret << "-nthreads" << threadCounts[m_threadsIndex]; @@ -673,8 +683,9 @@ bool TFarmTaskGroup::changeChunkSize(int chunksize) { TFarmTask *subTask = new TFarmTask( m_id + "." + toString(i, 2, '0'), subName, true, m_user, m_hostName, rb - ra + 1, m_priority, m_taskFilePath, m_outputPath, ra, rb, - m_step, m_shrink, m_multimedia, m_renderKeysOnly, m_chunkSize, - m_threadsIndex, m_maxTileSizeIndex, Overwrite_Off, false); + m_step, m_shrink, m_multimedia, m_renderKeysOnly, m_renderToFolders, + m_chunkSize, m_threadsIndex, m_maxTileSizeIndex, Overwrite_Off, + false); subTask->m_parentId = m_id; addTask(subTask); @@ -691,18 +702,17 @@ bool TFarmTaskGroup::changeChunkSize(int chunksize) { //------------------------------------------------------------------------------ -TFarmTaskGroup::TFarmTaskGroup(const QString &id, const QString &name, - const QString &user, const QString &host, - int stepCount, int priority, - const TFilePath &taskFilePath, - const TFilePath &outputPath, int from, int to, - int step, int shrink, int multimedia, - bool renderKeysOnly, int chunksize, - int threadsIndex, int maxTileSizeIndex) +TFarmTaskGroup::TFarmTaskGroup( + const QString &id, const QString &name, const QString &user, + const QString &host, int stepCount, int priority, + const TFilePath &taskFilePath, const TFilePath &outputPath, int from, + int to, int step, int shrink, int multimedia, bool renderKeysOnly, + bool renderToFolders, int chunksize, int threadsIndex, int maxTileSizeIndex) : TFarmTask(id, name, true, user, host, stepCount, priority, taskFilePath, outputPath, from, to, step, shrink, multimedia, renderKeysOnly, - chunksize, threadsIndex, maxTileSizeIndex, Overwrite_Off, false) + renderToFolders, chunksize, threadsIndex, maxTileSizeIndex, + Overwrite_Off, false) , m_imp(new Imp()) { int subCount = 0; if (chunksize > 0) subCount = tceil((to - from + 1) / (double)chunksize); @@ -720,8 +730,8 @@ TFarmTaskGroup::TFarmTaskGroup(const QString &id, const QString &name, TFarmTask *subTask = new TFarmTask( id + "." + toString(i, 2, '0'), subName, true, user, host, stepCount, priority, taskFilePath, outputPath, ra, rb, step, shrink, - multimedia, renderKeysOnly, chunksize, threadsIndex, - maxTileSizeIndex, Overwrite_Off, false); + multimedia, renderKeysOnly, renderToFolders, chunksize, + threadsIndex, maxTileSizeIndex, Overwrite_Off, false); subTask->m_parentId = id; addTask(subTask); @@ -742,7 +752,8 @@ TFarmTaskGroup::TFarmTaskGroup(const QString &id, const QString &name, const TFilePath &taskFilePath, OverwriteBehavior overwrite, bool onlyvisible) : TFarmTask(id, name, false, user, host, stepCount, priority, taskFilePath, - TFilePath(), 0, 0, 0, 0, 0, 0, 0, 0, 0, overwrite, onlyvisible) + TFilePath(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, overwrite, + onlyvisible) , m_imp(new Imp()) {} //------------------------------------------------------------------------------ diff --git a/toonz/sources/toonzlib/multimediarenderer.cpp b/toonz/sources/toonzlib/multimediarenderer.cpp index f4c47f15..c27d51e1 100644 --- a/toonz/sources/toonzlib/multimediarenderer.cpp +++ b/toonz/sources/toonzlib/multimediarenderer.cpp @@ -4,6 +4,7 @@ #include "toonz/multimediarenderer.h" #include "toonz/movierenderer.h" #include "trenderer.h" +#include "tsystem.h" // Scene structures #include "toonz/toonzscene.h" @@ -73,9 +74,11 @@ public: int m_multimediaMode; bool m_renderKeysOnly; + bool m_renderToFolders; Imp(ToonzScene *scene, const TFilePath &moviePath, int multimediaMode, - bool renderKeysOnly, int threadCount, bool cacheResults); + bool renderKeysOnly, bool renderToFolders, int threadCount, + bool cacheResults); ~Imp(); @@ -100,7 +103,8 @@ public: MultimediaRenderer::Imp::Imp(ToonzScene *scene, const TFilePath &moviePath, int multimediaMode, bool renderKeysOnly, - int threadCount, bool cacheResults) + bool renderToFolders, int threadCount, + bool cacheResults) : m_scene(scene) , m_fp(moviePath) , m_threadCount(threadCount) @@ -114,7 +118,8 @@ MultimediaRenderer::Imp::Imp(ToonzScene *scene, const TFilePath &moviePath, , m_currentFx(0) , m_currentFrame() , m_multimediaMode(multimediaMode) - , m_renderKeysOnly(renderKeysOnly) { + , m_renderKeysOnly(renderKeysOnly) + , m_renderToFolders(renderToFolders) { // Retrieve all fx nodes to be rendered in this process. scanSceneForRenderNodes(); } @@ -394,13 +399,39 @@ void MultimediaRenderer::Imp::start() { std::wstring fxNameNoSpaces(::removeSpaces(fxName)); std::wstring fxId(currFx->getFxId()); - std::wstring fpName = - m_fp.getWideName() + L"_" + columnName + - (columnId == columnName ? L"" : L"(" + columnId + L")") + - (fxId.empty() ? L"" : L"_" + fxName + (fxId == fxNameNoSpaces - ? L"" - : L"(" + fxId + L")")); - TFilePath movieFp(m_fp.withName(fpName)); + std::wstring fpName; + + TFilePath fp = m_fp; + + if (!m_renderToFolders) + fpName = fp.getWideName() + L"_" + columnName + + (columnId == columnName ? L"" : L"(" + columnId + L")") + + (fxId.empty() + ? L"" + : L"_" + fxName + + (fxId == fxNameNoSpaces ? L"" : L"(" + fxId + L")")); + else { + fp = fp.getParentDir() + TFilePath(fp.getWideName()) + + TFilePath(columnName + + (columnId == columnName ? L"" : L"(" + columnId + L")")) + + columnName; + fp = fp.withType(m_fp.getType()); + if (!TSystem::doesExistFileOrLevel(fp.getParentDir())) { + TFilePath parentDir = fp.getParentDir(); + try { + TSystem::mkDir(parentDir); + } catch (...) { + break; + } + } + fpName = columnName + + ((fxId.empty() || m_multimediaMode == 1) + ? L"" + : L"_" + fxName + + (fxId == fxNameNoSpaces ? L"" : L"(" + fxId + L")")); + } + + TFilePath movieFp(fp.withName(fpName)); // Initialize a MovieRenderer with our infos MovieRenderer movieRenderer(m_scene, movieFp, m_threadCount, false); @@ -487,9 +518,10 @@ void MultimediaRenderer::Imp::onRenderCompleted() { MultimediaRenderer::MultimediaRenderer(ToonzScene *scene, const TFilePath &moviePath, int multimediaMode, bool renderKeysOnly, - int threadCount, bool cacheResults) + bool renderToFolders, int threadCount, + bool cacheResults) : m_imp(new Imp(scene, moviePath, multimediaMode, renderKeysOnly, - threadCount, cacheResults)) { + renderToFolders, threadCount, cacheResults)) { m_imp->addRef(); } @@ -527,6 +559,12 @@ bool MultimediaRenderer::isRenderKeysOnly() const { //--------------------------------------------------------- +bool MultimediaRenderer::isRenderToFolders() const { + return m_imp->m_renderToFolders; +} + +//--------------------------------------------------------- + void MultimediaRenderer::setRenderSettings( const TRenderSettings &renderSettings) { // assert(m_imp->m_framesOnRendering.empty()); diff --git a/toonz/sources/toonzlib/outputproperties.cpp b/toonz/sources/toonzlib/outputproperties.cpp index fa171df6..7a03b73d 100644 --- a/toonz/sources/toonzlib/outputproperties.cpp +++ b/toonz/sources/toonzlib/outputproperties.cpp @@ -39,6 +39,7 @@ TOutputProperties::TOutputProperties() , m_whichLevels(false) , m_multimediaRendering(0) , m_renderKeysOnly(false) + , m_renderToFolders(false) , m_maxTileSizeIndex(0) , m_threadIndex(2) , m_subcameraPreview(false) @@ -62,7 +63,8 @@ TOutputProperties::TOutputProperties(const TOutputProperties &src) , m_offset(src.m_offset) , m_step(src.m_step) , m_multimediaRendering(src.m_multimediaRendering) - , m_renderKeysOnly(src.m_renderKeysOnly) + , m_renderKeysOnly(src.m_renderKeysOnly) + , m_renderToFolders(src.m_renderToFolders) , m_maxTileSizeIndex(src.m_maxTileSizeIndex) , m_threadIndex(src.m_threadIndex) , m_subcameraPreview(src.m_subcameraPreview) @@ -99,6 +101,7 @@ TOutputProperties &TOutputProperties::operator=(const TOutputProperties &src) { m_multimediaRendering = src.m_multimediaRendering; m_renderKeysOnly = src.m_renderKeysOnly; + m_renderToFolders = src.m_renderToFolders; m_maxTileSizeIndex = src.m_maxTileSizeIndex; m_threadIndex = src.m_threadIndex; m_subcameraPreview = src.m_subcameraPreview; diff --git a/toonz/sources/toonzlib/sceneproperties.cpp b/toonz/sources/toonzlib/sceneproperties.cpp index f74c32f4..6ebcbe4a 100644 --- a/toonz/sources/toonzlib/sceneproperties.cpp +++ b/toonz/sources/toonzlib/sceneproperties.cpp @@ -260,8 +260,12 @@ void TSceneProperties::saveData(TOStream &os) const { os.child("multimedia") << out.getMultimediaRendering(); // Save render keys only if enabled and multimedia set to anything except // None - if (out.getMultimediaRendering() && out.isRenderKeysOnly()) - os.child("renderKeysOnly") << (out.isRenderKeysOnly() ? 1 : 0); + if (out.getMultimediaRendering()) { + if (out.isRenderKeysOnly()) + os.child("renderKeysOnly") << (out.isRenderKeysOnly() ? 1 : 0); + if (out.isRenderToFolders()) + os.child("renderToFolders") << (out.isRenderToFolders() ? 1 : 0); + } os.child("threadsIndex") << out.getThreadIndex(); os.child("maxTileSizeIndex") << out.getMaxTileSizeIndex(); os.child("subcameraPrev") << (out.isSubcameraPreview() ? 1 : 0); @@ -597,6 +601,10 @@ void TSceneProperties::loadData(TIStream &is, bool isLoadingProject) { int renderKeysOnly; is >> renderKeysOnly; out.setRenderKeysOnly(renderKeysOnly == 1); + } else if (tagName == "renderToFolders") { + int renderToFolders; + is >> renderToFolders; + out.setRenderToFolders(renderToFolders == 1); } else if (tagName == "threadsIndex") { int j; is >> j;