Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define _CRT_SECURE_NO_WARNINGS (1)  //Warning treated as errors
Toshihiro Shimizu 890ddd
#define _CRT_SECURE_NO_DEPRECATE (1) //use of fopen deprecated
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Tnz includes (-.-')
Toshihiro Shimizu 890ddd
#include "../toonz/tapp.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TFarmController includes
Toshihiro Shimizu 890ddd
#include "tfarmcontroller.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzStdfx includes
Toshihiro Shimizu 890ddd
#include "stdfx/shaderfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/toonzfolders.h"
Toshihiro Shimizu 890ddd
#include "toonz/tlog.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjecttree.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "toonz/tproject.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/sceneproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsoundlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsoundcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcamera.h"
Toshihiro Shimizu 890ddd
#include "toonz/scenefx.h"
Toshihiro Shimizu 890ddd
#include "toonz/movierenderer.h"
Toshihiro Shimizu 890ddd
#include "toonz/multimediarenderer.h"
Toshihiro Shimizu 890ddd
#include "toutputproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/imagestyles.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzSound includes
Toshihiro Shimizu 890ddd
#include "tnzsound.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzImage includes
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
#include "tnzimage.h"
Toshihiro Shimizu 890ddd
#include "tflash.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#include "avicodecrestrictions.h"
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "tcli.h"
Toshihiro Shimizu 890ddd
#include "tunit.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
#include "tpassivecachemanager.h"
Toshihiro Shimizu 890ddd
//#include "tcacheresourcepool.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tsmartpointer.h"
Toshihiro Shimizu 890ddd
#include "tthread.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tmsgcore.h"
Toshihiro Shimizu 890ddd
#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tfilepath_io.h"
Toshihiro Shimizu 890ddd
#include "tpluginmanager.h"
Toshihiro Shimizu 890ddd
#include "tiio_std.h"
Toshihiro Shimizu 890ddd
#include "tsimplecolorstyles.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tvectorbrushstyle.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
kusano 46ab69
// TnzQt includes
kusano 46ab69
#include "toonzqt/pluginloader.h"
kusano 46ab69
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qapplication></qapplication>
Toshihiro Shimizu 890ddd
#include <qwaitcondition></qwaitcondition>
Toshihiro Shimizu 890ddd
#include <qmessagebox></qmessagebox>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace TCli;
Toshihiro Shimizu 890ddd
typedef ArgumentT<tfilepath> FilePathArgument;</tfilepath>
Toshihiro Shimizu 890ddd
typedef QualifierT<tfilepath> FilePathQualifier;</tfilepath>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
double currentCameraSize = 12;
Toshihiro Shimizu 890ddd
double getCurrentCameraSize()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return currentCameraSize;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Application names and versions
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// applicationName & Version compongono la registry root
Toshihiro Shimizu 890ddd
// applicationFullName e' la title bar (e compare dentro i .tnz)
Toshihiro Shimizu 890ddd
// rootVarName e' quello che dice di essere
Toshihiro Shimizu 890ddd
// systemVarPrefix viene prefissa a tutte le variabili nei registry
Toshihiro Shimizu 890ddd
//   (es <systemvarprefix>PROJECTS etc.)</systemvarprefix>
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const char *applicationName = "OpenToonz";
Toshihiro Shimizu 890ddd
const char *applicationVersion = "1.0";
Toshihiro Shimizu 890ddd
const char *applicationFullName = "OpenToonz 1.0";
Toshihiro Shimizu 890ddd
const char *rootVarName = "TOONZROOT";
Toshihiro Shimizu 890ddd
const char *systemVarPrefix = "TOONZ";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TODO: forse anche questo andrebbe in tnzbase
Toshihiro Shimizu 890ddd
// ci possono essere altri programmi offline oltre al tcomposer
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// fatalError
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void fatalError(string msg)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
	std::cout << msg << std::endl;
Toshihiro Shimizu 890ddd
	//MessageBox(0,msg.c_str(),"Fatal error",MB_ICONERROR);
Toshihiro Shimizu 890ddd
	exit(1);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	// TODO: Come si fa ad aggiungere un messaggio di errore qui?
Toshihiro Shimizu 890ddd
	std::cout << msg << std::endl;
Toshihiro Shimizu 890ddd
	abort();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline bool isBlank(char c)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return c == ' ' || c == '\t' || c == '\n';
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TODO: se questo sistema e' il modo Mac di emulare i registry di windows
Toshihiro Shimizu 890ddd
// allora **DEVE** essere messo in libreria. Parliamone.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
// setToonzFolder
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Ritorna il path della variabile passata come secondo argomento
Toshihiro Shimizu 890ddd
// entrambe vengono lette da un file di testo (filename).
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFilePath setToonzFolder(const TFilePath &filename, std::string toonzVar)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Tifstream is(filename);
Toshihiro Shimizu 890ddd
	if (!is)
Toshihiro Shimizu 890ddd
		return TFilePath();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	char buffer[1024];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while (is.getline(buffer, sizeof(buffer))) {
Toshihiro Shimizu 890ddd
		// le righe dentro toonzenv.txt sono del tipo
Toshihiro Shimizu 890ddd
		// export set TOONZPROJECT="....."
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// devo trovare la linea che contiene toonzVar
Toshihiro Shimizu 890ddd
		char *s = buffer;
Toshihiro Shimizu 890ddd
		while (isBlank(*s))
Toshihiro Shimizu 890ddd
			s++;
Toshihiro Shimizu 890ddd
		// Se la riga  vuota, o inizia per # o ! salto alla prossima
Toshihiro Shimizu 890ddd
		if (*s == '\0' || *s == '#' || *s == '!')
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		if (*s == '=')
Toshihiro Shimizu 890ddd
			continue; // errore: nome variabile non c'
Toshihiro Shimizu 890ddd
		char *t = s;
Toshihiro Shimizu 890ddd
		// Mi prendo la sottoStringa fino all'=
Toshihiro Shimizu 890ddd
		while (*t && *t != '=')
Toshihiro Shimizu 890ddd
			t++;
Toshihiro Shimizu 890ddd
		if (*t != '=')
Toshihiro Shimizu 890ddd
			continue; // errore: manca '='
Toshihiro Shimizu 890ddd
		char *q = t;
Toshihiro Shimizu 890ddd
		// Torno indietro fino al primo blank
Toshihiro Shimizu 890ddd
		while (q > s && !isBlank(*(q - 1)))
Toshihiro Shimizu 890ddd
			q--;
Toshihiro Shimizu 890ddd
		if (q == s)
Toshihiro Shimizu 890ddd
			continue; // non dovrebbe mai succedere: prima di '=' tutti blanks
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		string toonzVarString(q, t);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Confronto la stringa trovata con toonzVar, se   lei vado avanti.
Toshihiro Shimizu 890ddd
		if (toonzVar != toonzVarString)
Toshihiro Shimizu 890ddd
			continue; // errore: stringhe diverse
Toshihiro Shimizu 890ddd
		s = t + 1;
Toshihiro Shimizu 890ddd
		// Salto gli spazi
Toshihiro Shimizu 890ddd
		while (isBlank(*s))
Toshihiro Shimizu 890ddd
			s++;
Toshihiro Shimizu 890ddd
		if (*s == '\0')
Toshihiro Shimizu 890ddd
			continue; //errore: dst vuoto
Toshihiro Shimizu 890ddd
		t = s;
Toshihiro Shimizu 890ddd
		while (*t)
Toshihiro Shimizu 890ddd
			t++;
Toshihiro Shimizu 890ddd
		while (t > s && isBlank(*(t - 1)))
Toshihiro Shimizu 890ddd
			t--;
Toshihiro Shimizu 890ddd
		if (t == s)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		// ATTENZIONE : tolgo le virgolette !!
Toshihiro Shimizu 890ddd
		string pathName(s + 1, t - s - 2);
Toshihiro Shimizu 890ddd
		return TFilePath(pathName);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TFilePath();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
TStopWatch Sw1;
Toshihiro Shimizu 890ddd
TStopWatch Sw2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool UseRenderFarm = false;
Toshihiro Shimizu 890ddd
QString FarmControllerName;
Toshihiro Shimizu 890ddd
int FarmControllerPort;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFarmController *FarmController = 0;
Toshihiro Shimizu 890ddd
TUserLogAppend *m_userLog;
Toshihiro Shimizu 890ddd
QString TaskId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void tcomposerRunOutOfContMemHandler(unsigned long size)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 9eb50d
	string msg("Run out of contiguous memory: tried to allocate " + std::to_string(size >> 10) + " KB");
Toshihiro Shimizu 890ddd
	cout << msg << endl;
Toshihiro Shimizu 890ddd
	m_userLog->error(msg);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//The task will necessarily do something wrong. So we quit with an error code.
Toshihiro Shimizu 890ddd
	TImageCache::instance()->clear(true);
Toshihiro Shimizu 890ddd
	exit(2);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class MyMovieRenderListener : public MovieRenderer::Listener
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	MyMovieRenderListener(const TFilePath &fp, int frameCount, QWaitCondition &renderCompleted, bool stereo)
Toshihiro Shimizu 890ddd
		: m_fp(fp), m_frameCount(frameCount), m_frameCompletedCount(0), m_frameFailedCount(0), m_renderCompleted(renderCompleted), m_stereo(stereo)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool onFrameCompleted(int frame);
Toshihiro Shimizu 890ddd
	bool onFrameFailed(int frame, TException &e);
Toshihiro Shimizu 890ddd
	void onSequenceCompleted(const TFilePath &fp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath m_fp;
Toshihiro Shimizu 890ddd
	int m_frameCount;
Toshihiro Shimizu 890ddd
	int m_frameCompletedCount;
Toshihiro Shimizu 890ddd
	int m_frameFailedCount;
Toshihiro Shimizu 890ddd
	QWaitCondition &m_renderCompleted;
Toshihiro Shimizu 890ddd
	bool m_stereo;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool MyMovieRenderListener::onFrameCompleted(int frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFilePath fp = m_fp.withFrame(frame + 1);
Toshihiro Shimizu 890ddd
	string msg;
Toshihiro Shimizu 890ddd
	if (m_stereo)
Shinya Kitaoka 9eb50d
		msg = ::to_string(fp.withName(fp.getName() + "_l")) + " and " + ::to_string(fp.withName(fp.getName() + "_r")) + " computed";
Toshihiro Shimizu 890ddd
	else
Shinya Kitaoka 9eb50d
		msg = ::to_string(fp) + " computed";
Toshihiro Shimizu 890ddd
	cout << msg << endl;
Toshihiro Shimizu 890ddd
	m_userLog->info(msg);
Shinya Kitaoka eabf18
	DVGui::info(QString::fromStdString(msg));
Toshihiro Shimizu 890ddd
	if (FarmController) {
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			FarmController->taskProgress(TaskId, m_frameCompletedCount + m_frameFailedCount, m_frameCount, frame + 1, FrameDone);
Toshihiro Shimizu 890ddd
		} catch (...) {
Shinya Kitaoka 9eb50d
			msg = "Unable to connect to " + std::to_string(FarmControllerPort) + "@" + FarmControllerName.toStdString();
Toshihiro Shimizu 890ddd
			cout << msg;
Toshihiro Shimizu 890ddd
			m_userLog->error(msg);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_frameCompletedCount++;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool MyMovieRenderListener::onFrameFailed(int frame, TException &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFilePath fp = m_fp.withFrame(frame + 1);
Toshihiro Shimizu 890ddd
	string msg;
Shinya Kitaoka 9eb50d
	msg = ::to_string(fp) + " failed";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!e.getMessage().empty())
Shinya Kitaoka 9eb50d
		msg += ": " + ::to_string(e.getMessage());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	cout << msg << endl;
Toshihiro Shimizu 890ddd
	m_userLog->error(msg);
Toshihiro Shimizu 890ddd
	if (FarmController) {
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			FarmController->taskProgress(TaskId, m_frameCompletedCount + m_frameFailedCount, m_frameCount, frame + 1, FrameFailed);
Toshihiro Shimizu 890ddd
		} catch (...) {
Shinya Kitaoka 9eb50d
			msg = "Unable to connect to " + std::to_string(FarmControllerPort) + "@" + FarmControllerName.toStdString();
Toshihiro Shimizu 890ddd
			cout << msg;
Toshihiro Shimizu 890ddd
			m_userLog->error(msg);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_frameFailedCount++;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MyMovieRenderListener::onSequenceCompleted(const TFilePath &fp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	cout << endl;
Toshihiro Shimizu 890ddd
	QCoreApplication::instance()->quit();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class MyMultimediaRenderListener : public MultimediaRenderer::Listener
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TFilePath m_fp;
Toshihiro Shimizu 890ddd
	int m_frameCount;
Toshihiro Shimizu 890ddd
	int m_frameCompletedCount;
Toshihiro Shimizu 890ddd
	int m_frameFailedCount;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	MyMultimediaRenderListener(const TFilePath &fp, int frameCount)
Toshihiro Shimizu 890ddd
		: m_fp(fp), m_frameCount(frameCount), m_frameCompletedCount(0), m_frameFailedCount(0)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool onFrameCompleted(int frame, int column);
Toshihiro Shimizu 890ddd
	bool onFrameFailed(int frame, int column, TException &e);
Toshihiro Shimizu 890ddd
	void onSequenceCompleted(int column) {}
Toshihiro Shimizu 890ddd
	void onRenderCompleted() {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool MyMultimediaRenderListener::onFrameCompleted(int frame, int column)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int actualFrame = frame + 1;
Shinya Kitaoka 9eb50d
	string msg = ::to_string(m_fp) + ", column " + std::to_string(column) + ", frame " + std::to_string(actualFrame) + " computed";
Toshihiro Shimizu 890ddd
	cout << msg << endl;
Toshihiro Shimizu 890ddd
	m_userLog->info(msg);
Toshihiro Shimizu 890ddd
	if (FarmController) {
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			FarmController->taskProgress(TaskId, m_frameCompletedCount + m_frameFailedCount, m_frameCount, actualFrame, FrameDone);
Toshihiro Shimizu 890ddd
		} catch (...) {
Shinya Kitaoka 9eb50d
			msg = "Unable to connect to " + std::to_string(FarmControllerPort) + "@" + FarmControllerName.toStdString();
Toshihiro Shimizu 890ddd
			cout << msg;
Toshihiro Shimizu 890ddd
			m_userLog->error(msg);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_frameCompletedCount++;
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool MyMultimediaRenderListener::onFrameFailed(int frame, int column, TException &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int actualFrame = frame + 1;
Shinya Kitaoka 9eb50d
	string msg = ::to_string(m_fp) + ", column " + std::to_string(column) + ", frame " + std::to_string(actualFrame) + " failed";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!e.getMessage().empty())
Shinya Kitaoka 9eb50d
		msg += ": " + ::to_string(e.getMessage());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	cout << msg << endl;
Toshihiro Shimizu 890ddd
	m_userLog->error(msg);
Toshihiro Shimizu 890ddd
	if (FarmController) {
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			FarmController->taskProgress(TaskId, m_frameCompletedCount + m_frameFailedCount, m_frameCount, actualFrame, FrameFailed);
Toshihiro Shimizu 890ddd
		} catch (...) {
Shinya Kitaoka 9eb50d
			msg = "Unable to connect to " + std::to_string(FarmControllerPort) + "@" + FarmControllerName.toStdString();
Toshihiro Shimizu 890ddd
			cout << msg;
Toshihiro Shimizu 890ddd
			m_userLog->error(msg);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_frameFailedCount++;
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::pair<int, int=""> generateMovie(ToonzScene *scene,</int,>
Toshihiro Shimizu 890ddd
								  const TFilePath &fp,
Toshihiro Shimizu 890ddd
								  int r0, int r1,
Toshihiro Shimizu 890ddd
								  int step, int shrink,
Toshihiro Shimizu 890ddd
								  int threadCount,
Toshihiro Shimizu 890ddd
								  int maxTileSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QWaitCondition renderCompleted;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// riporto gli indici a base zero
Toshihiro Shimizu 890ddd
	r0 = r0 - 1;
Toshihiro Shimizu 890ddd
	r1 = r1 - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (r0 < 0)
Toshihiro Shimizu 890ddd
		r0 = 0;
Toshihiro Shimizu 890ddd
	if (r1 < 0 || r1 >= scene->getFrameCount())
Toshihiro Shimizu 890ddd
		r1 = scene->getFrameCount() - 1;
Toshihiro Shimizu 890ddd
	string msg;
Toshihiro Shimizu 890ddd
	assert(r1 >= r0);
Toshihiro Shimizu 890ddd
	TSceneProperties *sprop = scene->getProperties();
Toshihiro Shimizu 890ddd
	TOutputProperties outputSettings = *sprop->getOutputProperties();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	currentCameraSize = scene->getCurrentCamera()->getSize().lx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TDimension cameraSize = scene->getCurrentCamera()->getRes();
Toshihiro Shimizu 890ddd
	TSystem::touchParentDir(fp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	string ext = fp.getType();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
	if (ext == "avi") {
Toshihiro Shimizu 890ddd
		TPropertyGroup *props = scene->getProperties()->getOutputProperties()->getFileFormatProperties(ext);
Toshihiro Shimizu 890ddd
		string codecName = props->getProperty(0)->getValueAsString();
Toshihiro Shimizu 890ddd
		TDimension res = scene->getCurrentCamera()->getRes();
Shinya Kitaoka 9eb50d
		if (!AviCodecRestrictions::canWriteMovie(::to_wstring(codecName), res)) {
Toshihiro Shimizu 890ddd
			string msg("The resolution of the output camera does not fit with the options chosen for the output file format.");
Toshihiro Shimizu 890ddd
			m_userLog->error(msg);
Toshihiro Shimizu 890ddd
			exit(1);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Shinya Kitaoka 3bfa54
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double cameraXDpi, cameraYDpi;
Toshihiro Shimizu 890ddd
	TPointD camDpi = scene->getCurrentCamera()->getDpi();
Toshihiro Shimizu 890ddd
	cameraXDpi = camDpi.x;
Toshihiro Shimizu 890ddd
	cameraYDpi = camDpi.y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int which = outputSettings.getWhichLevels();
Toshihiro Shimizu 890ddd
	double stretchTo = (double)outputSettings.getRenderSettings().m_timeStretchTo;
Toshihiro Shimizu 890ddd
	double stretchFrom = (double)outputSettings.getRenderSettings().m_timeStretchFrom;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double timeStretchFactor = stretchFrom / stretchTo;
Toshihiro Shimizu 890ddd
	int numFrames = (int)((r1 - r0 + 1) / timeStretchFactor);
Toshihiro Shimizu 890ddd
	double r = (r0)*timeStretchFactor;
Toshihiro Shimizu 890ddd
	double stepd = step * timeStretchFactor;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int multimediaRender = outputSettings.getMultimediaRendering();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
	//    Multimedia render
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (multimediaRender) {
Toshihiro Shimizu 890ddd
		MultimediaRenderer multimediaRenderer(scene, fp, multimediaRender, threadCount);
Toshihiro Shimizu 890ddd
		TRenderSettings rs = outputSettings.getRenderSettings();
Toshihiro Shimizu 890ddd
		rs.m_maxTileSize = maxTileSize;
Toshihiro Shimizu 890ddd
		rs.m_shrinkX = rs.m_shrinkY = shrink;
Toshihiro Shimizu 890ddd
		multimediaRenderer.setRenderSettings(rs);
Toshihiro Shimizu 890ddd
		multimediaRenderer.setDpi(cameraXDpi, cameraYDpi);
Toshihiro Shimizu 890ddd
		multimediaRenderer.enablePrecomputing(true);
Toshihiro Shimizu 890ddd
		for (int i = 0; i < numFrames; i += step, r += stepd)
Toshihiro Shimizu 890ddd
			multimediaRenderer.addFrame(r);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		MyMultimediaRenderListener *listener =
Toshihiro Shimizu 890ddd
			new MyMultimediaRenderListener(fp,
Toshihiro Shimizu 890ddd
										   multimediaRenderer.getFrameCount() * multimediaRenderer.getColumnsCount());
Toshihiro Shimizu 890ddd
		multimediaRenderer.addListener(listener);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		multimediaRenderer.start();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//----------------- main thread remains above until render is done ----------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//NOTE: the passed total frame count "columns * frames" is an overestimate in this case:
Toshihiro Shimizu 890ddd
		//columns which do not appear on certain frames are not rendered. So, just realize the
Toshihiro Shimizu 890ddd
		//number of failed frames if any.
Toshihiro Shimizu 890ddd
		std::pair<int, int=""> framePair =</int,>
Toshihiro Shimizu 890ddd
			std::make_pair(listener->m_frameCount, listener->m_frameCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		delete listener;
Toshihiro Shimizu 890ddd
		return framePair;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
	//    Movie render
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		MovieRenderer movieRenderer(scene, fp, threadCount, false);
Toshihiro Shimizu 890ddd
		TRenderSettings rs = outputSettings.getRenderSettings();
Toshihiro Shimizu 890ddd
		rs.m_maxTileSize = maxTileSize;
Toshihiro Shimizu 890ddd
		rs.m_shrinkX = rs.m_shrinkY = shrink;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		movieRenderer.setRenderSettings(rs);
Toshihiro Shimizu 890ddd
		movieRenderer.setDpi(cameraXDpi, cameraYDpi);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		movieRenderer.enablePrecomputing(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		MyMovieRenderListener *listener = new MyMovieRenderListener(
Toshihiro Shimizu 890ddd
			fp, tceil((numFrames) / (float)step), renderCompleted, rs.m_stereoscopic);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		movieRenderer.addListener(listener);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int i = 0; i < numFrames; i += step, r += stepd) {
Toshihiro Shimizu 890ddd
			TFxPair fx;
Toshihiro Shimizu 890ddd
			if (rs.m_stereoscopic)
Toshihiro Shimizu 890ddd
				scene->shiftCameraX(-rs.m_stereoscopicShift / 2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			fx.m_frameA = (TRasterFxP)buildSceneFx(scene, scene->getXsheet(), r, which, shrink, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (rs.m_fieldPrevalence != TRenderSettings::NoField)
Toshihiro Shimizu 890ddd
				fx.m_frameB = (TRasterFxP)buildSceneFx(scene, scene->getXsheet(), r + 0.5 * timeStretchFactor, which, shrink, false);
Toshihiro Shimizu 890ddd
			else if (rs.m_stereoscopic) {
Toshihiro Shimizu 890ddd
				scene->shiftCameraX(rs.m_stereoscopicShift);
Toshihiro Shimizu 890ddd
				fx.m_frameB = (TRasterFxP)buildSceneFx(scene, scene->getXsheet(), r, which, shrink, false);
Toshihiro Shimizu 890ddd
				scene->shiftCameraX(-rs.m_stereoscopicShift / 2);
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				fx.m_frameB = TRasterFxP();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			movieRenderer.addFrame(r, fx);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		movieRenderer.start();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Start main loop
Toshihiro Shimizu 890ddd
		QCoreApplication::instance()->exec();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//----------------- tcomposer's main thread loops here ----------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//int frameCompleted = listener->m_frameCompletedCount;
Toshihiro Shimizu 890ddd
		std::pair<int, int=""> framePair =</int,>
Toshihiro Shimizu 890ddd
			std::make_pair(listener->m_frameCompletedCount, listener->m_frameCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		delete listener;
Toshihiro Shimizu 890ddd
		return framePair;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// main()
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//TODO: il main comincia a diventare troppo lungo. Forse val la pena
Toshihiro Shimizu 890ddd
// separarlo in varie funzioni
Toshihiro Shimizu 890ddd
// (tipo initToonzEnvironment(), parseCommandLine(), ecc)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DV_IMPORT_API void initStdFx();
Toshihiro Shimizu 890ddd
DV_IMPORT_API void initColorFx();
Toshihiro Shimizu 890ddd
int main(int argc, char *argv[])
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QApplication app(argc, argv);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Create a QObject destroyed just before app - see Tnz6's main.cpp for rationale
Toshihiro Shimizu 890ddd
	std::auto_ptr<qobject> mainScope(new QObject(&app));</qobject>
Toshihiro Shimizu 890ddd
	mainScope->setObjectName("mainScope");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#ifndef x64
Toshihiro Shimizu 890ddd
	//Store the floating point control word. It will be re-set before Toonz initialization
Toshihiro Shimizu 890ddd
	//has ended.
Toshihiro Shimizu 890ddd
	unsigned int fpWord = 0;
Toshihiro Shimizu 890ddd
	_controlfp_s(&fpWord, 0, 0);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Set the app's locale for numeric stuff to standard C. This is important for atof() and similar
Toshihiro Shimizu 890ddd
	//calls that are locale-dependant.
Toshihiro Shimizu 890ddd
	setlocale(LC_NUMERIC, "C");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Install run out of contiguous memory callback
Toshihiro Shimizu 890ddd
	TBigMemoryManager::instance()->setRunOutOfContiguousMemoryHandler(&tcomposerRunOutOfContMemHandler);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
//Define 64-bit precision for floating-point arithmetic. Please observe that the
Toshihiro Shimizu 890ddd
//initImageIo() call below would already impose this precision. This just wants to be
Toshihiro Shimizu 890ddd
//explicit.
Toshihiro Shimizu 890ddd
//_controlfp_s(0, 0, 0x10000);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Initialize thread components
Toshihiro Shimizu 890ddd
	TThread::init();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// questo definisce la registry root e inizializza TEnv
Toshihiro Shimizu 890ddd
	TEnv::setApplication(applicationName, applicationVersion);
Toshihiro Shimizu 890ddd
	TEnv::setApplicationFullName(applicationFullName);
Toshihiro Shimizu 890ddd
	TEnv::setRootVarName(rootVarName);
Toshihiro Shimizu 890ddd
	TEnv::setSystemVarPrefix(systemVarPrefix);
Toshihiro Shimizu 890ddd
	TSystem::hasMainLoop(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//QMessageBox::information(0, QString("eccolo"), QString("composer!"));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < argc; i++) //tmsg must be set as soon as it's possible
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QString str = argv[i];
Toshihiro Shimizu 890ddd
		if (str == "-tmsg") {
Toshihiro Shimizu 890ddd
			TMsgCore::instance()->connectTo(argv[i + 1]);
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (i == argc)
Toshihiro Shimizu 890ddd
		TMsgCore::instance()->connectTo("");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TODO: non va qui. Bisognerebbe semmai modificare l'implementazione
Toshihiro Shimizu 890ddd
// delle TEnv:: precedenti. Discutiamone
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Toshihiro Shimizu 890ddd
// StuffDir
Toshihiro Shimizu 890ddd
	QFileInfo infoStuff(QString("Toonz 7.1 stuff"));
Toshihiro Shimizu 890ddd
	TFilePath stuffDirPath(infoStuff.absoluteFilePath().toStdString());
Toshihiro Shimizu 890ddd
	TEnv::setStuffDir(stuffDirPath);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// controllo se la xxxroot e' definita e corrisponde ad un file esistente
Toshihiro Shimizu 890ddd
	TFilePath fp = TEnv::getStuffDir();
Toshihiro Shimizu 890ddd
	if (fp == TFilePath())
Shinya Kitaoka 9eb50d
		fatalError(string("Undefined: \"") + ::to_string(TEnv::getRootVarPath()) + "\"");
Toshihiro Shimizu 890ddd
	if (!TFileStatus(fp).isDirectory())
Shinya Kitaoka 9eb50d
		fatalError(string("Directory \"") + ::to_string(fp) + "\" not found or not readable");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath lRootDir = fp + "toonzfarm";
Toshihiro Shimizu 890ddd
	TFilePath logFilePath = lRootDir + "tcomposer.log";
Toshihiro Shimizu 890ddd
	m_userLog = new TUserLogAppend(logFilePath);
Toshihiro Shimizu 890ddd
	string msg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Initialize measure units
Toshihiro Shimizu 890ddd
	Preferences::instance();					 // Loads standard (linear) units
Toshihiro Shimizu 890ddd
	TMeasureManager::instance()->				 // Loads camera-related units
Toshihiro Shimizu 890ddd
		addCameraMeasures(getCurrentCameraSize); //
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePathSet fps = ToonzFolder::getProjectsFolders();
Toshihiro Shimizu 890ddd
	TFilePathSet::iterator fpIt;
Toshihiro Shimizu 890ddd
	for (fpIt = fps.begin(); fpIt != fps.end(); ++fpIt)
Toshihiro Shimizu 890ddd
		TProjectManager::instance()->addProjectsRoot(*fpIt);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath libraryFolder = ToonzFolder::getLibraryFolder();
Toshihiro Shimizu 890ddd
	TRasterImagePatternStrokeStyle::setRootDir(libraryFolder);
Toshihiro Shimizu 890ddd
	TVectorImagePatternStrokeStyle::setRootDir(libraryFolder);
Toshihiro Shimizu 890ddd
	TVectorBrushStyle::setRootDir(libraryFolder);
Toshihiro Shimizu 890ddd
	TPalette::setRootDir(libraryFolder);
Toshihiro Shimizu 890ddd
	TImageStyle::setLibraryDir(libraryFolder);
Toshihiro Shimizu 890ddd
	TFilePath cacheRoot = ToonzFolder::getCacheRootFolder();
Toshihiro Shimizu 890ddd
	if (cacheRoot.isEmpty())
Toshihiro Shimizu 890ddd
		cacheRoot = TEnv::getStuffDir() + "cache";
Toshihiro Shimizu 890ddd
	TImageCache::instance()->setRootDir(cacheRoot);
Toshihiro Shimizu 890ddd
	// #endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//  setCurrentModule("tcomposer");
Toshihiro Shimizu 890ddd
	TCli::FilePathArgument srcName("srcName", "Source file");
Toshihiro Shimizu 890ddd
	FilePathQualifier dstName("-o dstName", "Target file");
Toshihiro Shimizu 890ddd
	RangeQualifier range;
Toshihiro Shimizu 890ddd
	IntQualifier stepOpt("-step n", "Step");
Toshihiro Shimizu 890ddd
	IntQualifier shrinkOpt("-shrink n", "Shrink");
Toshihiro Shimizu 890ddd
	IntQualifier multimedia("-multimedia n", "Multimedia rendering mode");
Toshihiro Shimizu 890ddd
	StringQualifier farmData("-farm data", "TFarm Controller");
Toshihiro Shimizu 890ddd
	StringQualifier idq("-id n", "id");
Toshihiro Shimizu 890ddd
	StringQualifier nthreads("-nthreads n", "Number of rendering threads");
Toshihiro Shimizu 890ddd
	StringQualifier tileSize("-maxtilesize n", "Enable tile rendering of max n MB per tile");
Toshihiro Shimizu 890ddd
	StringQualifier tmsg("-tmsg val", "only internal use");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Usage usage(argv[0]);
Toshihiro Shimizu 890ddd
	usage.add(srcName + dstName + range + stepOpt + shrinkOpt + multimedia + farmData + idq + nthreads + tileSize + tmsg);
Toshihiro Shimizu 890ddd
	if (!usage.parse(argc, argv))
Toshihiro Shimizu 890ddd
		exit(1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TaskId = QString::fromStdString(idq.getValue());
Toshihiro Shimizu 890ddd
	string fdata = farmData.getValue();
Toshihiro Shimizu 890ddd
	if (fdata.empty())
Toshihiro Shimizu 890ddd
		UseRenderFarm = false;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		UseRenderFarm = true;
Toshihiro Shimizu 890ddd
		string::size_type pos = fdata.find('@');
Toshihiro Shimizu 890ddd
		if (pos == string::npos)
Toshihiro Shimizu 890ddd
			UseRenderFarm = false;
Toshihiro Shimizu 890ddd
		else {
Shinya Kitaoka 9eb50d
			FarmControllerPort = std::stoi(fdata.substr(0, pos));
Toshihiro Shimizu 890ddd
			FarmControllerName = QString::fromStdString(fdata.substr(pos + 1));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (UseRenderFarm) {
Toshihiro Shimizu 890ddd
		TFarmControllerFactory factory;
Toshihiro Shimizu 890ddd
		factory.create(FarmControllerName, FarmControllerPort, &FarmController);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
kusano 46ab69
	while (!PluginLoader::load_entries(""))
kusano 46ab69
		app.processEvents();
kusano 46ab69
Toshihiro Shimizu 890ddd
	std::pair<int, int=""> framePair(1, 0);</int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		Tiio::defineStd();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		initImageIo();
Toshihiro Shimizu 890ddd
		Tiio::defineStd();
Toshihiro Shimizu 890ddd
		initSoundIo();
Toshihiro Shimizu 890ddd
		initStdFx();
Toshihiro Shimizu 890ddd
		initColorFx();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		loadShaderInterfaces(ToonzFolder::getLibraryFolder() + TFilePath("shaders"));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TFilePath srcFilePath = srcName.getValue();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			srcFilePath = TSystem::toLocalPath(srcFilePath);
Toshihiro Shimizu 890ddd
		} catch (...) {
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//---------------------------------------------------------
Toshihiro Shimizu 890ddd
		msg = "Loading " + srcFilePath.getName();
Toshihiro Shimizu 890ddd
		cout << endl
Toshihiro Shimizu 890ddd
			 << msg << endl;
Toshihiro Shimizu 890ddd
		m_userLog->info(msg);
Toshihiro Shimizu 890ddd
		TProjectManager *pm = TProjectManager::instance();
Toshihiro Shimizu 890ddd
		// pm->enableTabMode(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TProjectP project = pm->loadSceneProject(srcFilePath);
Toshihiro Shimizu 890ddd
		if (!project) {
Toshihiro Shimizu 890ddd
			msg = "Couldn't find the project"; //+ project->getName().getName();
Toshihiro Shimizu 890ddd
			cerr << msg << endl;
Toshihiro Shimizu 890ddd
			m_userLog->error(msg);
Toshihiro Shimizu 890ddd
			return -2;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		msg = "project: " + project->getName().getName();
Toshihiro Shimizu 890ddd
		cout << msg << endl;
Toshihiro Shimizu 890ddd
		m_userLog->info(msg);
Toshihiro Shimizu 890ddd
		// pm->setCurrentProject(project, false); // false => temporaneamente
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		Sw1.start();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!TSystem::doesExistFileOrLevel(srcFilePath))
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
		ToonzScene *scene = new ToonzScene();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TImageStyle::setCurrentScene(scene);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			Sw2.start();
Toshihiro Shimizu 890ddd
			scene->load(srcFilePath);
Toshihiro Shimizu 890ddd
			Sw2.stop();
Toshihiro Shimizu 890ddd
		} catch (TException &e) {
Shinya Kitaoka 9eb50d
			cout << ::to_string(e.getMessage()) << endl;
Shinya Kitaoka 9eb50d
			m_userLog->error(::to_string(e.getMessage()));
Toshihiro Shimizu 890ddd
			return -2;
Toshihiro Shimizu 890ddd
		} catch (...) {
Toshihiro Shimizu 890ddd
			string msg;
Shinya Kitaoka 9eb50d
			msg = "There were problems loading the scene " + ::to_string(srcFilePath) +
Toshihiro Shimizu 890ddd
				  ".\n Some files may be missing.";
Toshihiro Shimizu 890ddd
			cout << msg << endl;
Toshihiro Shimizu 890ddd
			m_userLog->error(msg);
Toshihiro Shimizu 890ddd
			//return false;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		msg = "scene loaded";
Toshihiro Shimizu 890ddd
		cout << "scene loaded" << endl;
Toshihiro Shimizu 890ddd
		m_userLog->info(msg);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TFilePath dstFilePath;
Toshihiro Shimizu 890ddd
		if (dstName.isSelected())
Toshihiro Shimizu 890ddd
			dstFilePath = dstName.getValue();
Toshihiro Shimizu 890ddd
		else {
Toshihiro Shimizu 890ddd
			dstFilePath = scene->getProperties()->getOutputProperties()->getPath();
Toshihiro Shimizu 890ddd
			if (dstFilePath == TFilePath())
Toshihiro Shimizu 890ddd
				dstFilePath = TFilePath("+outputs") + "$scenename.tif";
Toshihiro Shimizu 890ddd
			else if (dstFilePath.getName() == "")
Toshihiro Shimizu 890ddd
				dstFilePath = (dstFilePath.getParentDir() + scene->getSceneName()).withType(dstFilePath.getType());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		dstFilePath = scene->decodeFilePath(dstFilePath);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//---------------------------------------------------------
Toshihiro Shimizu 890ddd
		msg = "Generating " + dstFilePath.getName();
Toshihiro Shimizu 890ddd
		cout << endl
Toshihiro Shimizu 890ddd
			 << "Generating " << dstFilePath << endl
Toshihiro Shimizu 890ddd
			 << endl;
Toshihiro Shimizu 890ddd
		m_userLog->info(msg);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TFilePath theDstFilePath = dstFilePath;
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			theDstFilePath = TSystem::toLocalPath(dstFilePath);
Toshihiro Shimizu 890ddd
		} catch (...) {
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int r0 = -1, r1 = -1, step = 1, shrink = 1;
Toshihiro Shimizu 890ddd
		TOutputProperties *outProp = scene->getProperties()->getOutputProperties();
Toshihiro Shimizu 890ddd
		int scene_from, scene_to, scene_step;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		outProp->getRange(scene_from, scene_to, scene_step);
Toshihiro Shimizu 890ddd
		int scene_shrink = outProp->getRenderSettings().m_shrinkX;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (scene_from == 0 && scene_to == -1) {
Toshihiro Shimizu 890ddd
			scene_from = 1;
Toshihiro Shimizu 890ddd
			scene_to = scene->getFrameCount();
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			scene_from++;
Toshihiro Shimizu 890ddd
			scene_to++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (range.isSelected()) {
Toshihiro Shimizu 890ddd
			r0 = range.getFrom();
Toshihiro Shimizu 890ddd
			r1 = range.getTo();
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			r0 = scene_from;
Toshihiro Shimizu 890ddd
			r1 = scene_to;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (stepOpt.isSelected())
Toshihiro Shimizu 890ddd
			step = stepOpt.getValue();
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			step = scene_step;
Toshihiro Shimizu 890ddd
		if (shrinkOpt.isSelected())
Toshihiro Shimizu 890ddd
			shrink = shrinkOpt.getValue();
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			shrink = scene_shrink;
Toshihiro Shimizu 890ddd
		if (multimedia.isSelected())
Toshihiro Shimizu 890ddd
			scene->getProperties()->getOutputProperties()->setMultimediaRendering(multimedia.getValue());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Retrieve Thread count
Toshihiro Shimizu 890ddd
		const int procCount = TSystem::getProcessorCount();
Toshihiro Shimizu 890ddd
		int threadCount;
Toshihiro Shimizu 890ddd
		const int threadCounts[3] = {1, procCount / 2, procCount};
Toshihiro Shimizu 890ddd
		if (nthreads.isSelected()) {
Toshihiro Shimizu 890ddd
			QString threadCountStr = QString::fromStdString(nthreads.getValue());
Toshihiro Shimizu 890ddd
			threadCount =
Toshihiro Shimizu 890ddd
				(threadCountStr == "single") ? threadCounts[0] : (threadCountStr == "half") ? threadCounts[1] : (threadCountStr == "all") ? threadCounts[2] : threadCountStr.toInt();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (threadCount <= 0) {
Toshihiro Shimizu 890ddd
				cout << "Qualifier 'nthreads': bad input" << endl;
Toshihiro Shimizu 890ddd
				exit(1);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			int threadIndex = outProp->getThreadIndex();
Toshihiro Shimizu 890ddd
			threadCount = threadCounts[threadIndex];
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		threadCount = tcrop(1, procCount, threadCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Retrieve max tile size (raster granularity)
Toshihiro Shimizu 890ddd
		int maxTileSize;
Toshihiro Shimizu 890ddd
		const int maxTileSizes[4] = {
Toshihiro Shimizu 890ddd
			(std::numeric_limits<int>::max)(),</int>
Toshihiro Shimizu 890ddd
			TOutputProperties::LargeVal,
Toshihiro Shimizu 890ddd
			TOutputProperties::MediumVal,
Toshihiro Shimizu 890ddd
			TOutputProperties::SmallVal};
Toshihiro Shimizu 890ddd
		if (tileSize.isSelected()) {
Toshihiro Shimizu 890ddd
			QString tileSizeStr = QString::fromStdString(tileSize.getValue());
Toshihiro Shimizu 890ddd
			maxTileSize =
Toshihiro Shimizu 890ddd
				(tileSizeStr == "none") ? maxTileSizes[0] : (tileSizeStr == "large") ? maxTileSizes[1] : (tileSizeStr == "medium") ? maxTileSizes[2] : (tileSizeStr == "small") ? maxTileSizes[3] : tileSizeStr.toInt();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (maxTileSize <= 0) {
Toshihiro Shimizu 890ddd
				cout << "Qualifier 'maxtilesize': bad input" << endl;
Toshihiro Shimizu 890ddd
				exit(1);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			int maxTileSizeIndex = outProp->getMaxTileSizeIndex();
Toshihiro Shimizu 890ddd
			maxTileSize = maxTileSizes[maxTileSizeIndex];
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9eb50d
		m_userLog->info("Threads count: " + std::to_string(threadCount));
Toshihiro Shimizu 890ddd
		if (maxTileSize != (std::numeric_limits<int>::max)())</int>
Shinya Kitaoka 9eb50d
			m_userLog->info("Render tile: " + std::to_string(maxTileSize));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Disable the Passive cache manager. It has no sense if it cannot write on disk...
Toshihiro Shimizu 890ddd
		//TCacheResourcePool::instance();   //Needs to be instanced before TPassiveCacheManager...
Toshihiro Shimizu 890ddd
		TPassiveCacheManager::instance()->setEnabled(false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#ifndef x64
Toshihiro Shimizu 890ddd
		//On 32-bit architecture, there could be cases in which initialization could alter the
Toshihiro Shimizu 890ddd
		//FPU floating point control word. I've seen this happen when loading some AVI coded (VFAPI),
Toshihiro Shimizu 890ddd
		//where 80-bit internal precision was used instead of the standard 64-bit (much faster and
Toshihiro Shimizu 890ddd
		//sufficient - especially considering that x86 truncates to 64-bit representation anyway).
Toshihiro Shimizu 890ddd
		//IN ANY CASE, revert to the original control word.
Toshihiro Shimizu 890ddd
		//In the x64 case these precision changes simply should not take place up to _controlfp_s
Toshihiro Shimizu 890ddd
		//documentation.
Toshihiro Shimizu 890ddd
		_controlfp_s(0, fpWord, -1);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		framePair = generateMovie(scene, theDstFilePath, r0, r1, step, shrink, threadCount, maxTileSize);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		Sw1.stop();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9eb50d
		m_userLog->info("Raster Allocation Peak: " + std::to_string(TBigMemoryManager::instance()->getAllocationPeak()) + " KB");
Shinya Kitaoka 9eb50d
		m_userLog->info("Raster Allocation Mean: " + std::to_string(TBigMemoryManager::instance()->getAllocationMean()) + " KB");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9eb50d
		msg = "Compositing completed in " + ::to_string(Sw1.getTotalTime() / 1000.0, 2) + " seconds";
Shinya Kitaoka 9eb50d
		string msg2 = "\n" + ::to_string(Sw2.getTotalTime() / 1000.0, 2) + " seconds spent on loading" + "\n" +
Shinya Kitaoka 9eb50d
					  ::to_string(TStopWatch::global(0).getTotalTime() / 1000.0, 2) + " seconds spent on saving" + "\n" +
Shinya Kitaoka 9eb50d
					  ::to_string(TStopWatch::global(8).getTotalTime() / 1000.0, 2) + " seconds spent on rendering" + "\n";
Toshihiro Shimizu 890ddd
		cout << msg + msg2;
Toshihiro Shimizu 890ddd
		m_userLog->info(msg + msg2);
Shinya Kitaoka eabf18
		DVGui::info(QString::fromStdString(msg));
Toshihiro Shimizu 890ddd
		TImageCache::instance()->clear(true);
Toshihiro Shimizu 890ddd
	} catch (TException &e) {
Shinya Kitaoka 9eb50d
		msg = "Untrapped exception: " + ::to_string(e.getMessage()),
Toshihiro Shimizu 890ddd
		cout << msg << endl;
Toshihiro Shimizu 890ddd
		m_userLog->error(msg);
Toshihiro Shimizu 890ddd
		TImageCache::instance()->clear(true);
Toshihiro Shimizu 890ddd
	} catch (...) {
Toshihiro Shimizu 890ddd
		cout << "Untrapped exception" << endl;
Toshihiro Shimizu 890ddd
		m_userLog->error("Untrapped exception");
Toshihiro Shimizu 890ddd
		TImageCache::instance()->clear(true);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (framePair.first != framePair.second)
Toshihiro Shimizu 890ddd
		return -1;
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}