Skip to content

Commit

Permalink
render queue (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
shun-iwasawa authored Dec 18, 2024
1 parent 08f4bc1 commit f8f263f
Show file tree
Hide file tree
Showing 21 changed files with 780 additions and 330 deletions.
17 changes: 10 additions & 7 deletions sources/iwproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ IwProject::IwProject()
: m_settings(new ViewSettings())
, m_workAreaSize(0, 0)
, m_renderSettings(new RenderSettings())
, m_outputSettings(new OutputSettings())
, m_renderQueue(new RenderQueue())
, m_shapeTagSettings(new ShapeTagSettings())
, m_path("Untitled")
, m_prevFrom(-1)
Expand Down Expand Up @@ -127,8 +127,8 @@ void IwProject::saveData(QXmlStreamWriter& writer) {

// OutputOptions
writer.writeComment("Output Settings");
writer.writeStartElement("OutputOptions");
m_outputSettings->saveData(writer);
writer.writeStartElement("RenderQueue");
m_renderQueue->saveData(writer);
writer.writeEndElement();

// ShapeTagSettings
Expand Down Expand Up @@ -193,9 +193,12 @@ void IwProject::loadData(QXmlStreamReader& reader) {
else if (reader.name() == "MorphOptions")
m_renderSettings->loadData(reader);

// OutputOptions
// OutputOptions : old version data
else if (reader.name() == "OutputOptions")
m_outputSettings->loadData(reader);
m_renderQueue->loadPrevVersionData(reader);
// Render Queue
else if (reader.name() == "RenderQueue")
m_renderQueue->loadData(reader);

// ShapeTag Settings
else if (reader.name() == "ShapeTags")
Expand Down Expand Up @@ -228,8 +231,8 @@ QString IwProject::getProjectName() { return QFileInfo(m_path).baseName(); }
//---------------------------------------------------
// frameに対する保存パスを返す
//---------------------------------------------------
QString IwProject::getOutputPath(int frame, QString formatStr) {
return m_outputSettings->getPath(frame, getProjectName(), formatStr);
QString IwProject::getOutputPath(int frame, QString formatStr, int queueId) {
return m_renderQueue->getPath(frame, getProjectName(), formatStr, queueId);
}

//---------------------------------------------------
Expand Down
11 changes: 7 additions & 4 deletions sources/iwproject.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Preferences;
class QXmlStreamWriter;
class QXmlStreamReader;
class RenderSettings;
class OutputSettings;
class RenderQueue;
class ShapeTagSettings;

class IwLayer;
Expand All @@ -43,7 +43,8 @@ class IwProject {
RenderSettings* m_renderSettings;

// 出力設定
OutputSettings* m_outputSettings;
RenderQueue* m_renderQueue;
// OutputSettings* m_outputSettings;

// MultiFrameモードがONのときに編集されるフレームはtrue
// プロジェクトファイルには保存されない
Expand Down Expand Up @@ -109,13 +110,15 @@ class IwProject {
RenderSettings* getRenderSettings() { return m_renderSettings; }

// 出力設定
OutputSettings* getOutputSettings() { return m_outputSettings; }
// OutputSettings* getOutputSettings() { return m_outputSettings; }
RenderQueue* getRenderQueue() { return m_renderQueue; }

// パスからプロジェクト名を抜き出して返す
QString getProjectName();

// frameに対する保存パスを返す
QString getOutputPath(int frame, QString formatStr = QString());
QString getOutputPath(int frame, QString formatStr = QString(),
int queueId = -1);

//-------------
// MultiFrame関係
Expand Down
131 changes: 78 additions & 53 deletions sources/iwrendercommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ void IwRenderCommand::onPreview() {
int prevFrom, prevTo;
project->getPreviewRange(prevFrom, prevTo);

OutputSettings* settings = project->getRenderQueue()->currentOutputSettings();

// 現在のフレームからタスクを積んでいく
QList<int> cuedFrames;
if (currentFrame < prevFrom || currentFrame > prevTo) {
Expand All @@ -58,7 +60,8 @@ void IwRenderCommand::onPreview() {
}

for (auto frame : cuedFrames) {
IwRenderInstance* previewTask = new IwRenderInstance(frame, project, true);
IwRenderInstance* previewTask =
new IwRenderInstance(frame, project, settings, true);
connect(previewTask, SIGNAL(renderStarted(int, unsigned int)),
IwApp::instance()->getCurrentProject(),
SLOT(onPreviewRenderStarted(int, unsigned int)),
Expand All @@ -76,72 +79,94 @@ void IwRenderCommand::onPreview() {

void RenderInvoke_Worker::run() {
for (int frame : m_frames) {
IwRenderInstance(frame, m_project, false, m_popup).doRender();
IwRenderInstance(frame, m_project, m_settings, false, m_popup).doRender();
emit frameFinished();
}
// レンダリングが終わったら完了にする
// m_settings->setRenderState(OutputSettings::Done);
}

void IwRenderCommand::onRender() {
IwProject* project = IwApp::instance()->getCurrentProject()->getProject();
if (!project) return;

// 計算範囲を求める
// 何フレーム計算するか
OutputSettings* settings = project->getOutputSettings();
OutputSettings::SaveRange saveRange = settings->getSaveRange();

if (settings->getDirectory().isEmpty()) {
QMessageBox::warning(0, QObject::tr("Output Settings Error"),
QObject::tr("Output directory is not set."));
QList<OutputSettings*> activeItems = project->getRenderQueue()->activeItems();
if (activeItems.isEmpty()) {
QMessageBox::warning(
0, QObject::tr("Output Settings Error"),
QObject::tr("There is no active items in the Render Queue."));
return;
}

QDir dir(settings->getDirectory());
if (!dir.exists()) {
QMessageBox::StandardButton ret = QMessageBox::question(
0, tr("Do you want to create folder?"),
QString("The folder %1 does not exist.\nDo you want to create it?")
.arg(settings->getDirectory()),
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
if (ret == QMessageBox::Yes) {
std::cout << "yes" << std::endl;
// フォルダ作る
bool ok = dir.mkpath(dir.path());
if (!ok) {
QMessageBox::critical(
0, tr("Failed to create folder."),
QString("Failed to create folder %1.").arg(dir.path()));
return;
}
} else
return;
}

if (saveRange.endFrame == -1)
saveRange.endFrame = project->getProjectFrameLength() - 1;

int frameAmount =
(int)((saveRange.endFrame - saveRange.startFrame) / saveRange.stepFrame) +
1;

// プログレスバー作る
RenderProgressPopup progressPopup(project);
// 各フレームについて
QList<int> frames;
for (int i = 0; i < frameAmount; i++) {
// フレームを求める
int frame = saveRange.startFrame + i * saveRange.stepFrame;
frames.append(frame);
// progressPopup.show();
std::cout << (void*)(&progressPopup) << std::endl;
for (auto settings : activeItems) {
progressPopup.startItem(settings);

// 計算範囲を求める
// 何フレーム計算するか
// OutputSettings* settings = project->getOutputSettings();
OutputSettings::SaveRange saveRange = settings->getSaveRange();

if (settings->getDirectory().isEmpty()) {
QMessageBox::warning(0, QObject::tr("Output Settings Error"),
QObject::tr("Output directory is not set."));
continue;
}

QDir dir(settings->getDirectory());
if (!dir.exists()) {
QMessageBox::StandardButton ret = QMessageBox::question(
0, tr("Do you want to create folder?"),
QString("The folder %1 does not exist.\nDo you want to create it?")
.arg(settings->getDirectory()),
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
if (ret == QMessageBox::Yes) {
std::cout << "yes" << std::endl;
// フォルダ作る
bool ok = dir.mkpath(dir.path());
if (!ok) {
QMessageBox::critical(
0, tr("Failed to create folder."),
QString("Failed to create folder %1.").arg(dir.path()));
continue;
}
} else {
continue;
}
}

if (saveRange.endFrame == -1)
saveRange.endFrame = project->getProjectFrameLength() - 1;

int frameAmount = (int)((saveRange.endFrame - saveRange.startFrame) /
saveRange.stepFrame) +
1;

// 各フレームについて
QList<int> frames;
for (int i = 0; i < frameAmount; i++) {
// フレームを求める
int frame = saveRange.startFrame + i * saveRange.stepFrame;
frames.append(frame);
}

// マットレイヤ情報を格納
settings->obtainMatteLayerNames();

RenderInvoke_Worker* task =
new RenderInvoke_Worker(frames, project, settings, &progressPopup);
connect(task, SIGNAL(frameFinished()), &progressPopup,
SLOT(onFrameFinished()), Qt::QueuedConnection);
QThreadPool::globalInstance()->reserveThread();
task->start();
progressPopup.exec();
QThreadPool::globalInstance()->releaseThread();

// QThreadPool::globalInstance()->waitForDone();
}

RenderInvoke_Worker* task =
new RenderInvoke_Worker(frames, project, &progressPopup);
connect(task, SIGNAL(frameFinished()), &progressPopup,
SLOT(onFrameFinished()), Qt::QueuedConnection);
QThreadPool::globalInstance()->reserveThread();
task->start();
progressPopup.exec();
QThreadPool::globalInstance()->releaseThread();
}

IwRenderCommand renderCommand;
15 changes: 10 additions & 5 deletions sources/iwrendercommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@
#include <QList>
class IwProject;
class RenderProgressPopup;
class OutputSettings;
//---------------------------------------------------

class RenderInvoke_Worker : public QThread {
Q_OBJECT
QList<int>& m_frames;
QList<int> m_frames;
IwProject* m_project;
RenderProgressPopup* m_popup;
RenderProgressPopup* m_popup = nullptr;
OutputSettings* m_settings;
void run() override;

public:
RenderInvoke_Worker(QList<int>& frames, IwProject* project,
RenderProgressPopup* popup)
: m_frames(frames), m_project(project), m_popup(popup) {}
RenderInvoke_Worker(QList<int> frames, IwProject* project,
OutputSettings* settings, RenderProgressPopup* popup)
: m_frames(frames)
, m_project(project)
, m_popup(popup)
, m_settings(settings) {}

signals:
void frameFinished();
Expand Down
18 changes: 10 additions & 8 deletions sources/iwrenderinstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,11 @@ unsigned int taskId = 0;

//---------------------------------------------------
IwRenderInstance::IwRenderInstance(int frame, IwProject* project,
bool isPreview, RenderProgressPopup* popup)
OutputSettings* os, bool isPreview,
RenderProgressPopup* popup)
: m_frame(frame)
, m_project(project)
, m_outputSettings(os)
, m_isPreview(isPreview)
, m_popup(popup)
, m_warpStyle(WARP_FIXED)
Expand Down Expand Up @@ -157,7 +159,7 @@ void IwRenderInstance::doRender() {
morphedRaster->fill(TPixel64::Transparent);
if (isCanceled()) return;

int targetShapeTag = m_project->getOutputSettings()->getShapeTagId();
int targetShapeTag = m_outputSettings->getShapeTagId();
// リサンプル
ResampleMode resampleMode = m_project->getRenderSettings()->getResampleMode();

Expand Down Expand Up @@ -223,7 +225,7 @@ void IwRenderInstance::doPreview() {
// 結果を収めるラスタ
QSize workAreaSize = m_project->getWorkAreaSize();

int targetShapeTag = m_project->getOutputSettings()->getShapeTagId();
int targetShapeTag = m_outputSettings->getShapeTagId();

// 下から、各レイヤについて
for (int lay = m_project->getLayerCount() - 1; lay >= 0; lay--) {
Expand Down Expand Up @@ -1128,14 +1130,14 @@ void IwRenderInstance::saveImage(TRaster64P ras) {
TRasterImageP img(ras);

// ファイルパスを得る
QString path = m_project->getOutputPath(m_frame);
QString path =
m_outputSettings->getPath(m_frame, m_project->getProjectName());

OutputSettings* settings = m_project->getOutputSettings();

QString ext = OutputSettings::getStandardExtension(settings->getSaver());
QString ext =
OutputSettings::getStandardExtension(m_outputSettings->getSaver());

TPropertyGroup* prop =
settings->getFileFormatProperties(settings->getSaver());
m_outputSettings->getFileFormatProperties(m_outputSettings->getSaver());

TImageWriterP writer(TFilePath(path.toStdWString()));
writer->setProperties(prop);
Expand Down
7 changes: 5 additions & 2 deletions sources/iwrenderinstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <array>
#include <QRunnable>
#include <QImage>

#include "trasterimage.h"
#include "halfedge.h"
#include "rendersettings.h"
Expand All @@ -22,6 +23,7 @@ class IwLayer;
class ShapePair;
class RenderProgressPopup;
class IwRenderInstance;
class OutputSettings;

enum CorrVecId { CORRVEC_SRC = 0, CORRVEC_DST, CORRVEC_MIDDLE };
enum WarpStyle { WARP_FIXED = 0, WARP_SLIDING };
Expand Down Expand Up @@ -119,6 +121,7 @@ class IwRenderInstance : public QObject, public QRunnable {

int m_frame;
IwProject* m_project;
OutputSettings* m_outputSettings;
bool m_isPreview;
RenderProgressPopup* m_popup;
int m_precision;
Expand Down Expand Up @@ -176,8 +179,8 @@ class IwRenderInstance : public QObject, public QRunnable {
//--------------------------------

public:
IwRenderInstance(int frame, IwProject* project, bool isPreview,
RenderProgressPopup* popup = nullptr);
IwRenderInstance(int frame, IwProject* project, OutputSettings* settings,
bool isPreview, RenderProgressPopup* popup = nullptr);
void doPreview();
void doRender();

Expand Down
3 changes: 2 additions & 1 deletion sources/iwshapepairselection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,8 @@ void SetShapeTagUndo::setTag(bool isUndo) {
if (m_project->isCurrent()) {
IwApp::instance()->getCurrentProject()->notifyProjectChanged();
// レンダリングに関わるタグの場合シグナルを出す
if (m_tagId == m_project->getOutputSettings()->getShapeTagId())
if (m_tagId ==
m_project->getRenderQueue()->currentOutputSettings()->getShapeTagId())
IwApp::instance()->getCurrentProject()->notifyPreviewCacheInvalidated();
}
}
Expand Down
3 changes: 2 additions & 1 deletion sources/iwtrianglecache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ bool IwTriangleCache::isFrameValid(int frame) {
IwProject* prj = IwApp::instance()->getCurrentProject()->getProject();
if (!prj) return false;

int targetShapeTag = prj->getOutputSettings()->getShapeTagId();
int targetShapeTag =
prj->getRenderQueue()->currentOutputSettings()->getShapeTagId();

// 各レイヤについて
for (int i = 0; i < prj->getLayerCount(); i++) {
Expand Down
Binary file modified sources/loc/IwaWarper_ja.qm
Binary file not shown.
Loading

0 comments on commit f8f263f

Please sign in to comment.