Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#define _CRT_SECURE_NO_WARNINGS (1)   // Warning treated as errors
Shinya Kitaoka 120a6e
#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
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
double currentCameraSize = 12;
Shinya Kitaoka 120a6e
double getCurrentCameraSize() { return currentCameraSize; }
Dave 5a9475
}  // namespace
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
Shinya Kitaoka 120a6e
namespace {
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
shun-iwasawa f39ea0
const char *rootVarName     = "TOONZROOT";
shun-iwasawa f39ea0
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
Shinya Kitaoka 120a6e
void fatalError(string msg) {
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  std::cout << msg << std::endl;
Shinya Kitaoka 120a6e
  // MessageBox(0,msg.c_str(),"Fatal error",MB_ICONERROR);
Shinya Kitaoka 120a6e
  exit(1);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  // TODO: Come si fa ad aggiungere un messaggio di errore qui?
Shinya Kitaoka 120a6e
  std::cout << msg << std::endl;
Shinya Kitaoka 120a6e
  abort();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline bool isBlank(char c) { return c == ' ' || c == '\t' || c == '\n'; }
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
Shinya Kitaoka 120a6e
TFilePath setToonzFolder(const TFilePath &filename, std::string toonzVar) {
Shinya Kitaoka 120a6e
  Tifstream is(filename);
Shinya Kitaoka 120a6e
  if (!is) return TFilePath();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  char buffer[1024];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (is.getline(buffer, sizeof(buffer))) {
Shinya Kitaoka 120a6e
    // le righe dentro toonzenv.txt sono del tipo
Shinya Kitaoka 120a6e
    // export set TOONZPROJECT="....."
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // devo trovare la linea che contiene toonzVar
Shinya Kitaoka 120a6e
    char *s = buffer;
Shinya Kitaoka 120a6e
    while (isBlank(*s)) s++;
Shinya Kitaoka 120a6e
    // Se la riga  vuota, o inizia per # o ! salto alla prossima
Shinya Kitaoka 120a6e
    if (*s == '\0' || *s == '#' || *s == '!') continue;
Shinya Kitaoka 120a6e
    if (*s == '=') continue;  // errore: nome variabile non c'
Shinya Kitaoka 120a6e
    char *t = s;
Shinya Kitaoka 120a6e
    // Mi prendo la sottoStringa fino all'=
Shinya Kitaoka 120a6e
    while (*t && *t != '=') t++;
Shinya Kitaoka 120a6e
    if (*t != '=') continue;  // errore: manca '='
Shinya Kitaoka 120a6e
    char *q = t;
Shinya Kitaoka 120a6e
    // Torno indietro fino al primo blank
Shinya Kitaoka 120a6e
    while (q > s && !isBlank(*(q - 1))) q--;
Shinya Kitaoka 120a6e
    if (q == s)
Shinya Kitaoka 120a6e
      continue;  // non dovrebbe mai succedere: prima di '=' tutti blanks
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    string toonzVarString(q, t);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Confronto la stringa trovata con toonzVar, se   lei vado avanti.
Shinya Kitaoka 120a6e
    if (toonzVar != toonzVarString) continue;  // errore: stringhe diverse
Shinya Kitaoka 120a6e
    s = t + 1;
Shinya Kitaoka 120a6e
    // Salto gli spazi
Shinya Kitaoka 120a6e
    while (isBlank(*s)) s++;
Shinya Kitaoka 120a6e
    if (*s == '\0') continue;  // errore: dst vuoto
Shinya Kitaoka 120a6e
    t = s;
Shinya Kitaoka 120a6e
    while (*t) t++;
Shinya Kitaoka 120a6e
    while (t > s && isBlank(*(t - 1))) t--;
Shinya Kitaoka 120a6e
    if (t == s) continue;
Shinya Kitaoka 120a6e
    // ATTENZIONE : tolgo le virgolette !!
Shinya Kitaoka 120a6e
    string pathName(s + 1, t - s - 2);
Shinya Kitaoka 120a6e
    return TFilePath(pathName);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return TFilePath();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
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
Shinya Kitaoka 120a6e
void tcomposerRunOutOfContMemHandler(unsigned long size) {
Shinya Kitaoka 120a6e
  string msg("Run out of contiguous memory: tried to allocate " +
Shinya Kitaoka 120a6e
             std::to_string(size >> 10) + " KB");
Shinya Kitaoka 120a6e
  cout << msg << endl;
Shinya Kitaoka 120a6e
  m_userLog->error(msg);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // The task will necessarily do something wrong. So we quit with an error
Shinya Kitaoka 120a6e
  // code.
Shinya Kitaoka 120a6e
  TImageCache::instance()->clear(true);
Shinya Kitaoka 120a6e
  exit(2);
Toshihiro Shimizu 890ddd
}
Dave 5a9475
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class MyMovieRenderListener final : public MovieRenderer::Listener {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  MyMovieRenderListener(const TFilePath &fp, int frameCount,
Shinya Kitaoka 120a6e
                        QWaitCondition &renderCompleted, bool stereo)
Shinya Kitaoka 120a6e
      : m_fp(fp)
Shinya Kitaoka 120a6e
      , m_frameCount(frameCount)
Shinya Kitaoka 120a6e
      , m_frameCompletedCount(0)
Shinya Kitaoka 120a6e
      , m_frameFailedCount(0)
Shinya Kitaoka 120a6e
      , m_renderCompleted(renderCompleted)
Shinya Kitaoka 120a6e
      , m_stereo(stereo) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  bool onFrameCompleted(int frame) override;
Shinya Kitaoka 473e70
  bool onFrameFailed(int frame, TException &e) override;
Shinya Kitaoka 473e70
  void onSequenceCompleted(const TFilePath &fp) override;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath m_fp;
Shinya Kitaoka 120a6e
  int m_frameCount;
Shinya Kitaoka 120a6e
  int m_frameCompletedCount;
Shinya Kitaoka 120a6e
  int m_frameFailedCount;
Shinya Kitaoka 120a6e
  QWaitCondition &m_renderCompleted;
Shinya Kitaoka 120a6e
  bool m_stereo;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool MyMovieRenderListener::onFrameCompleted(int frame) {
Shinya Kitaoka 120a6e
  TFilePath fp = m_fp.withFrame(frame + 1);
Shinya Kitaoka 120a6e
  string msg;
Shinya Kitaoka 120a6e
  if (m_stereo)
Shinya Kitaoka 120a6e
    msg = ::to_string(fp.withName(fp.getName() + "_l")) + " and " +
Shinya Kitaoka 120a6e
          ::to_string(fp.withName(fp.getName() + "_r")) + " computed";
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    msg = ::to_string(fp) + " computed";
Shinya Kitaoka 120a6e
  cout << msg << endl;
Shinya Kitaoka 120a6e
  m_userLog->info(msg);
Shinya Kitaoka 120a6e
  DVGui::info(QString::fromStdString(msg));
Shinya Kitaoka 120a6e
  if (FarmController) {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      FarmController->taskProgress(TaskId,
Shinya Kitaoka 120a6e
                                   m_frameCompletedCount + m_frameFailedCount,
Shinya Kitaoka 120a6e
                                   m_frameCount, frame + 1, FrameDone);
Shinya Kitaoka 120a6e
    } catch (...) {
Shinya Kitaoka 120a6e
      msg = "Unable to connect to " + std::to_string(FarmControllerPort) + "@" +
Shinya Kitaoka 120a6e
            FarmControllerName.toStdString();
Shinya Kitaoka 120a6e
      cout << msg;
Shinya Kitaoka 120a6e
      m_userLog->error(msg);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_frameCompletedCount++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool MyMovieRenderListener::onFrameFailed(int frame, TException &e) {
Shinya Kitaoka 120a6e
  TFilePath fp = m_fp.withFrame(frame + 1);
Shinya Kitaoka 120a6e
  string msg;
Shinya Kitaoka 120a6e
  msg = ::to_string(fp) + " failed";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!e.getMessage().empty()) msg += ": " + ::to_string(e.getMessage());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  cout << msg << endl;
Shinya Kitaoka 120a6e
  m_userLog->error(msg);
Shinya Kitaoka 120a6e
  if (FarmController) {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      FarmController->taskProgress(TaskId,
Shinya Kitaoka 120a6e
                                   m_frameCompletedCount + m_frameFailedCount,
Shinya Kitaoka 120a6e
                                   m_frameCount, frame + 1, FrameFailed);
Shinya Kitaoka 120a6e
    } catch (...) {
Shinya Kitaoka 120a6e
      msg = "Unable to connect to " + std::to_string(FarmControllerPort) + "@" +
Shinya Kitaoka 120a6e
            FarmControllerName.toStdString();
Shinya Kitaoka 120a6e
      cout << msg;
Shinya Kitaoka 120a6e
      m_userLog->error(msg);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_frameFailedCount++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MyMovieRenderListener::onSequenceCompleted(const TFilePath &fp) {
Shinya Kitaoka 120a6e
  cout << endl;
Shinya Kitaoka 120a6e
  QCoreApplication::instance()->quit();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class MyMultimediaRenderListener final : public MultimediaRenderer::Listener {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TFilePath m_fp;
Shinya Kitaoka 120a6e
  int m_frameCount;
Shinya Kitaoka 120a6e
  int m_frameCompletedCount;
Shinya Kitaoka 120a6e
  int m_frameFailedCount;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  MyMultimediaRenderListener(const TFilePath &fp, int frameCount)
Shinya Kitaoka 120a6e
      : m_fp(fp)
Shinya Kitaoka 120a6e
      , m_frameCount(frameCount)
Shinya Kitaoka 120a6e
      , m_frameCompletedCount(0)
Shinya Kitaoka 120a6e
      , m_frameFailedCount(0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  bool onFrameCompleted(int frame, int column) override;
Shinya Kitaoka 473e70
  bool onFrameFailed(int frame, int column, TException &e) override;
Shinya Kitaoka 473e70
  void onSequenceCompleted(int column) override {}
Shinya Kitaoka 473e70
  void onRenderCompleted() override {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool MyMultimediaRenderListener::onFrameCompleted(int frame, int column) {
Shinya Kitaoka 120a6e
  int actualFrame = frame + 1;
Shinya Kitaoka 120a6e
  string msg      = ::to_string(m_fp) + ", column " + std::to_string(column) +
Shinya Kitaoka 120a6e
               ", frame " + std::to_string(actualFrame) + " computed";
Shinya Kitaoka 120a6e
  cout << msg << endl;
Shinya Kitaoka 120a6e
  m_userLog->info(msg);
Shinya Kitaoka 120a6e
  if (FarmController) {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      FarmController->taskProgress(TaskId,
Shinya Kitaoka 120a6e
                                   m_frameCompletedCount + m_frameFailedCount,
Shinya Kitaoka 120a6e
                                   m_frameCount, actualFrame, FrameDone);
Shinya Kitaoka 120a6e
    } catch (...) {
Shinya Kitaoka 120a6e
      msg = "Unable to connect to " + std::to_string(FarmControllerPort) + "@" +
Shinya Kitaoka 120a6e
            FarmControllerName.toStdString();
Shinya Kitaoka 120a6e
      cout << msg;
Shinya Kitaoka 120a6e
      m_userLog->error(msg);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_frameCompletedCount++;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool MyMultimediaRenderListener::onFrameFailed(int frame, int column,
Shinya Kitaoka 120a6e
                                               TException &e) {
Shinya Kitaoka 120a6e
  int actualFrame = frame + 1;
Shinya Kitaoka 120a6e
  string msg      = ::to_string(m_fp) + ", column " + std::to_string(column) +
Shinya Kitaoka 120a6e
               ", frame " + std::to_string(actualFrame) + " failed";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!e.getMessage().empty()) msg += ": " + ::to_string(e.getMessage());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  cout << msg << endl;
Shinya Kitaoka 120a6e
  m_userLog->error(msg);
Shinya Kitaoka 120a6e
  if (FarmController) {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      FarmController->taskProgress(TaskId,
Shinya Kitaoka 120a6e
                                   m_frameCompletedCount + m_frameFailedCount,
Shinya Kitaoka 120a6e
                                   m_frameCount, actualFrame, FrameFailed);
Shinya Kitaoka 120a6e
    } catch (...) {
Shinya Kitaoka 120a6e
      msg = "Unable to connect to " + std::to_string(FarmControllerPort) + "@" +
Shinya Kitaoka 120a6e
            FarmControllerName.toStdString();
Shinya Kitaoka 120a6e
      cout << msg;
Shinya Kitaoka 120a6e
      m_userLog->error(msg);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_frameFailedCount++;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static std::pair<int, int=""> generateMovie(ToonzScene *scene, const TFilePath &fp,</int,>
Campbell Barton 8c6c57
                                         int r0, int r1, int step, int shrink,
Campbell Barton 8c6c57
                                         int threadCount, int maxTileSize) {
Shinya Kitaoka 120a6e
  QWaitCondition renderCompleted;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // riporto gli indici a base zero
Shinya Kitaoka 120a6e
  r0 = r0 - 1;
Shinya Kitaoka 120a6e
  r1 = r1 - 1;
Toshihiro Shimizu 890ddd
shun-iwasawa 9a8615
  if (r0 < 0) r0 = 0;
Shinya Kitaoka 120a6e
  if (r1 < 0 || r1 >= scene->getFrameCount()) r1 = scene->getFrameCount() - 1;
Shinya Kitaoka 120a6e
  string msg;
Shinya Kitaoka 120a6e
  assert(r1 >= r0);
Shinya Kitaoka 120a6e
  TSceneProperties *sprop          = scene->getProperties();
Shinya Kitaoka 120a6e
  TOutputProperties outputSettings = *sprop->getOutputProperties();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  currentCameraSize = scene->getCurrentCamera()->getSize().lx;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TDimension cameraSize = scene->getCurrentCamera()->getRes();
Shinya Kitaoka 120a6e
  TSystem::touchParentDir(fp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  string ext = fp.getType();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  if (ext == "avi") {
Shinya Kitaoka 120a6e
    TPropertyGroup *props =
Shinya Kitaoka 120a6e
        scene->getProperties()->getOutputProperties()->getFileFormatProperties(
Shinya Kitaoka 120a6e
            ext);
Shinya Kitaoka 120a6e
    string codecName = props->getProperty(0)->getValueAsString();
Shinya Kitaoka 120a6e
    TDimension res   = scene->getCurrentCamera()->getRes();
Shinya Kitaoka 120a6e
    if (!AviCodecRestrictions::canWriteMovie(::to_wstring(codecName), res)) {
Shinya Kitaoka 120a6e
      string msg(
Shinya Kitaoka 120a6e
          "The resolution of the output camera does not fit with the options "
Shinya Kitaoka 120a6e
          "chosen for the output file format.");
Shinya Kitaoka 120a6e
      m_userLog->error(msg);
Shinya Kitaoka 120a6e
      exit(1);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 3bfa54
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double cameraXDpi, cameraYDpi;
Shinya Kitaoka 120a6e
  TPointD camDpi = scene->getCurrentCamera()->getDpi();
Shinya Kitaoka 120a6e
  cameraXDpi     = camDpi.x;
Shinya Kitaoka 120a6e
  cameraYDpi     = camDpi.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int which        = outputSettings.getWhichLevels();
Shinya Kitaoka 120a6e
  double stretchTo = (double)outputSettings.getRenderSettings().m_timeStretchTo;
Shinya Kitaoka 120a6e
  double stretchFrom =
Shinya Kitaoka 120a6e
      (double)outputSettings.getRenderSettings().m_timeStretchFrom;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double timeStretchFactor = stretchFrom / stretchTo;
Shinya Kitaoka 120a6e
  int numFrames            = (int)((r1 - r0 + 1) / timeStretchFactor);
Shinya Kitaoka 120a6e
  double r                 = (r0)*timeStretchFactor;
Shinya Kitaoka 120a6e
  double stepd             = step * timeStretchFactor;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int multimediaRender = outputSettings.getMultimediaRendering();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //---------------------------------------------------------
Shinya Kitaoka 120a6e
  //    Multimedia render
Shinya Kitaoka 120a6e
  //---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (multimediaRender) {
Shinya Kitaoka 120a6e
    MultimediaRenderer multimediaRenderer(scene, fp, multimediaRender,
Shinya Kitaoka 120a6e
                                          threadCount);
Shinya Kitaoka 120a6e
    TRenderSettings rs = outputSettings.getRenderSettings();
Shinya Kitaoka 120a6e
    rs.m_maxTileSize   = maxTileSize;
Shinya Kitaoka 120a6e
    rs.m_shrinkX = rs.m_shrinkY = shrink;
Shinya Kitaoka 120a6e
    multimediaRenderer.setRenderSettings(rs);
Shinya Kitaoka 120a6e
    multimediaRenderer.setDpi(cameraXDpi, cameraYDpi);
Shinya Kitaoka 120a6e
    multimediaRenderer.enablePrecomputing(true);
Shinya Kitaoka 120a6e
    for (int i = 0; i < numFrames; i += step, r += stepd)
Shinya Kitaoka 120a6e
      multimediaRenderer.addFrame(r);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    MyMultimediaRenderListener *listener = new MyMultimediaRenderListener(
Shinya Kitaoka 120a6e
        fp, multimediaRenderer.getFrameCount() *
Shinya Kitaoka 120a6e
                multimediaRenderer.getColumnsCount());
Shinya Kitaoka 120a6e
    multimediaRenderer.addListener(listener);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    multimediaRenderer.start();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //----------------- main thread remains above until render is done
Shinya Kitaoka 120a6e
    //----------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // NOTE: the passed total frame count "columns * frames" is an overestimate
Shinya Kitaoka 120a6e
    // in this case:
Shinya Kitaoka 120a6e
    // columns which do not appear on certain frames are not rendered. So, just
Shinya Kitaoka 120a6e
    // realize the
Shinya Kitaoka 120a6e
    // number of failed frames if any.
Shinya Kitaoka 120a6e
    std::pair<int, int=""> framePair =</int,>
Shinya Kitaoka 120a6e
        std::make_pair(listener->m_frameCount, listener->m_frameCount);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    delete listener;
Shinya Kitaoka 120a6e
    return framePair;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //---------------------------------------------------------
Shinya Kitaoka 120a6e
  //    Movie render
Shinya Kitaoka 120a6e
  //---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    MovieRenderer movieRenderer(scene, fp, threadCount, false);
Shinya Kitaoka 120a6e
    TRenderSettings rs = outputSettings.getRenderSettings();
Shinya Kitaoka 120a6e
    rs.m_maxTileSize   = maxTileSize;
Shinya Kitaoka 120a6e
    rs.m_shrinkX = rs.m_shrinkY = shrink;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    movieRenderer.setRenderSettings(rs);
Shinya Kitaoka 120a6e
    movieRenderer.setDpi(cameraXDpi, cameraYDpi);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    movieRenderer.enablePrecomputing(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    MyMovieRenderListener *listener =
Shinya Kitaoka 120a6e
        new MyMovieRenderListener(fp, tceil((numFrames) / (float)step),
Shinya Kitaoka 120a6e
                                  renderCompleted, rs.m_stereoscopic);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    movieRenderer.addListener(listener);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int i = 0; i < numFrames; i += step, r += stepd) {
Shinya Kitaoka 120a6e
      TFxPair fx;
Shinya Kitaoka 120a6e
      if (rs.m_stereoscopic) scene->shiftCameraX(-rs.m_stereoscopicShift / 2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      fx.m_frameA = (TRasterFxP)buildSceneFx(scene, scene->getXsheet(), r,
Shinya Kitaoka 120a6e
                                             which, shrink, false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (rs.m_fieldPrevalence != TRenderSettings::NoField)
Shinya Kitaoka 120a6e
        fx.m_frameB = (TRasterFxP)buildSceneFx(scene, scene->getXsheet(),
Shinya Kitaoka 120a6e
                                               r + 0.5 * timeStretchFactor,
Shinya Kitaoka 120a6e
                                               which, shrink, false);
Shinya Kitaoka 120a6e
      else if (rs.m_stereoscopic) {
Shinya Kitaoka 120a6e
        scene->shiftCameraX(rs.m_stereoscopicShift);
Shinya Kitaoka 120a6e
        fx.m_frameB = (TRasterFxP)buildSceneFx(scene, scene->getXsheet(), r,
Shinya Kitaoka 120a6e
                                               which, shrink, false);
Shinya Kitaoka 120a6e
        scene->shiftCameraX(-rs.m_stereoscopicShift / 2);
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        fx.m_frameB = TRasterFxP();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      movieRenderer.addFrame(r, fx);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    movieRenderer.start();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Start main loop
Shinya Kitaoka 120a6e
    QCoreApplication::instance()->exec();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //----------------- tcomposer's main thread loops here ----------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // int frameCompleted = listener->m_frameCompletedCount;
Shinya Kitaoka 120a6e
    std::pair<int, int=""> framePair =</int,>
Shinya Kitaoka 120a6e
        std::make_pair(listener->m_frameCompletedCount, listener->m_frameCount);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    delete listener;
Shinya Kitaoka 120a6e
    return framePair;
Shinya Kitaoka 120a6e
  }
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
Shinya Kitaoka 120a6e
// 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)
Dave 5a9475
// TODO: the main starts getting too long. Perhaps it is worth
Dave 5a9475
// separated into various functions
Dave 5a9475
// (type initToonzEnvironment (), ParseCommandLine (), etc.)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DV_IMPORT_API void initStdFx();
Toshihiro Shimizu 890ddd
DV_IMPORT_API void initColorFx();
Shinya Kitaoka 120a6e
int main(int argc, char *argv[]) {
shun-iwasawa 9a8615
  TCli::UsageLine usageLine;
shun-iwasawa 9a8615
  //  setCurrentModule("tcomposer");
shun-iwasawa 9a8615
  TCli::FilePathArgument srcName("srcName", "Source file");
shun-iwasawa 9a8615
  FilePathQualifier dstName("-o dstName", "Target file");
shun-iwasawa 9a8615
  RangeQualifier range;
shun-iwasawa 9a8615
  IntQualifier stepOpt("-step n", "Step");
shun-iwasawa 9a8615
  IntQualifier shrinkOpt("-shrink n", "Shrink");
shun-iwasawa 9a8615
  IntQualifier multimedia("-multimedia n", "Multimedia rendering mode");
shun-iwasawa 9a8615
  StringQualifier farmData("-farm data", "TFarm Controller");
shun-iwasawa 9a8615
  StringQualifier idq("-id n", "id");
shun-iwasawa 9a8615
  StringQualifier nthreads("-nthreads n", "Number of rendering threads");
shun-iwasawa 9a8615
  StringQualifier tileSize("-maxtilesize n",
shun-iwasawa 9a8615
                           "Enable tile rendering of max n MB per tile");
shun-iwasawa 9a8615
  StringQualifier tmsg("-tmsg val", "only internal use");
shun-iwasawa 9a8615
  usageLine = srcName + dstName + range + stepOpt + shrinkOpt + multimedia +
shun-iwasawa 9a8615
              farmData + idq + nthreads + tileSize + tmsg;
shun-iwasawa 9a8615
shun-iwasawa 9a8615
  // system path qualifiers
shun-iwasawa 9a8615
  std::map<qstring, std::unique_ptr<tcli::qualifiert<tfilepath="">>></qstring,>
shun-iwasawa 9a8615
      systemPathQualMap;
shun-iwasawa 9a8615
  QString qualKey  = QString("%1ROOT").arg(systemVarPrefix);
shun-iwasawa 9a8615
  QString qualName = QString("-%1 folderpath").arg(qualKey);
shun-iwasawa 9a8615
  QString qualHelp =
shun-iwasawa 9a8615
      QString(
shun-iwasawa 9a8615
          "%1 path. It will automatically set other system paths to %1 "
shun-iwasawa 9a8615
          "unless individually specified with other qualifiers.")
shun-iwasawa 9a8615
          .arg(qualKey);
shun-iwasawa 9a8615
  systemPathQualMap[qualKey].reset(new TCli::QualifierT<tfilepath>(</tfilepath>
shun-iwasawa 9a8615
      qualName.toStdString(), qualHelp.toStdString()));
shun-iwasawa 9a8615
  usageLine = usageLine + *systemPathQualMap[qualKey];
shun-iwasawa 9a8615
shun-iwasawa 9a8615
  const std::map<std::string, std::string=""> &spm = TEnv::getSystemPathMap();</std::string,>
shun-iwasawa 9a8615
  for (auto itr = spm.begin(); itr != spm.end(); ++itr) {
shun-iwasawa 9a8615
    qualKey = QString("%1%2")
shun-iwasawa 9a8615
                  .arg(systemVarPrefix)
shun-iwasawa 9a8615
                  .arg(QString::fromStdString((*itr).first));
shun-iwasawa 9a8615
    qualName = QString("-%1 folderpath").arg(qualKey);
shun-iwasawa 9a8615
    qualHelp = QString("%1 path.").arg(qualKey);
shun-iwasawa 9a8615
    systemPathQualMap[qualKey].reset(new TCli::QualifierT<tfilepath>(</tfilepath>
shun-iwasawa 9a8615
        qualName.toStdString(), qualHelp.toStdString()));
shun-iwasawa 9a8615
    usageLine = usageLine + *systemPathQualMap[qualKey];
shun-iwasawa 9a8615
  }
shun-iwasawa 9a8615
shun-iwasawa 9a8615
  Usage usage(argv[0]);
shun-iwasawa 9a8615
  usage.add(usageLine);
shun-iwasawa 9a8615
  if (!usage.parse(argc, argv)) exit(1);
shun-iwasawa 9a8615
shun-iwasawa 9a8615
  QHash<qstring, qstring=""> argumentPathValues;</qstring,>
shun-iwasawa 9a8615
  for (auto q_itr = systemPathQualMap.begin(); q_itr != systemPathQualMap.end();
shun-iwasawa 9a8615
       ++q_itr) {
shun-iwasawa 9a8615
    if (q_itr->second->isSelected())
shun-iwasawa 9a8615
      argumentPathValues.insert(q_itr->first,
shun-iwasawa 9a8615
                                q_itr->second->getValue().getQString());
shun-iwasawa 9a8615
  }
shun-iwasawa 9a8615
Shinya Kitaoka 120a6e
  QApplication app(argc, argv);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Create a QObject destroyed just before app - see Tnz6's main.cpp for
Shinya Kitaoka 120a6e
  // rationale
Shinya Kitaoka 2a7129
  std::unique_ptr<qobject> mainScope(new QObject(&app));</qobject>
Shinya Kitaoka 120a6e
  mainScope->setObjectName("mainScope");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#ifndef x64
Shinya Kitaoka 120a6e
  // Store the floating point control word. It will be re-set before Toonz
Shinya Kitaoka 120a6e
  // initialization
Shinya Kitaoka 120a6e
  // has ended.
Shinya Kitaoka 120a6e
  unsigned int fpWord = 0;
Shinya Kitaoka 120a6e
  _controlfp_s(&fpWord, 0, 0);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Set the app's locale for numeric stuff to standard C. This is important for
Shinya Kitaoka 120a6e
  // atof() and similar
Shinya Kitaoka 120a6e
  // calls that are locale-dependant.
Shinya Kitaoka 120a6e
  setlocale(LC_NUMERIC, "C");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Install run out of contiguous memory callback
Shinya Kitaoka 120a6e
  TBigMemoryManager::instance()->setRunOutOfContiguousMemoryHandler(
Shinya Kitaoka 120a6e
      &tcomposerRunOutOfContMemHandler);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
// Define 64-bit precision for floating-point arithmetic. Please observe that
Shinya Kitaoka 120a6e
// the
Shinya Kitaoka 120a6e
// initImageIo() call below would already impose this precision. This just wants
Shinya Kitaoka 120a6e
// to be
Shinya Kitaoka 120a6e
// explicit.
Toshihiro Shimizu 890ddd
//_controlfp_s(0, 0, 0x10000);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Initialize thread components
Shinya Kitaoka 120a6e
  TThread::init();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // questo definisce la registry root e inizializza TEnv
Shinya Kitaoka 120a6e
  TEnv::setRootVarName(rootVarName);
Shinya Kitaoka 120a6e
  TEnv::setSystemVarPrefix(systemVarPrefix);
shun-iwasawa 9a8615
shun-iwasawa 7f4819
  QCoreApplication::setOrganizationName("OpenToonz");
shun-iwasawa 7f4819
  QCoreApplication::setOrganizationDomain("");
shun-iwasawa 7f4819
  QCoreApplication::setApplicationName(
shun-iwasawa 45fcf4
      QString::fromStdString(TEnv::getApplicationName()));
shun-iwasawa 7f4819
shun-iwasawa 9a8615
  QHash<qstring, qstring="">::const_iterator argItr =</qstring,>
shun-iwasawa 9a8615
      argumentPathValues.constBegin();
shun-iwasawa 9a8615
  while (argItr != argumentPathValues.constEnd()) {
shun-iwasawa 9a8615
    if (!TEnv::setArgPathValue(argItr.key().toStdString(),
shun-iwasawa 9a8615
                               argItr.value().toStdString()))
shun-iwasawa 9a8615
      cerr << "The qualifier " << argItr.key().toStdString()
shun-iwasawa 9a8615
           << " is not a valid key name. Skipping." << endl;
shun-iwasawa 9a8615
    ++argItr;
shun-iwasawa 9a8615
  }
shun-iwasawa 9a8615
Shinya Kitaoka 120a6e
  TSystem::hasMainLoop(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // QMessageBox::information(0, QString("eccolo"), QString("composer!"));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < argc; i++)  // tmsg must be set as soon as it's possible
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    QString str = argv[i];
Shinya Kitaoka 120a6e
    if (str == "-tmsg") {
Shinya Kitaoka 120a6e
      TMsgCore::instance()->connectTo(argv[i + 1]);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i == argc) TMsgCore::instance()->connectTo("");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // controllo se la xxxroot e' definita e corrisponde ad un file esistente
Shinya Kitaoka 120a6e
  TFilePath fp = TEnv::getStuffDir();
Shinya Kitaoka 120a6e
  if (fp == TFilePath())
Shinya Kitaoka 120a6e
    fatalError(string("Undefined: \"") + ::to_string(TEnv::getRootVarPath()) +
Shinya Kitaoka 120a6e
               "\"");
Shinya Kitaoka 120a6e
  if (!TFileStatus(fp).isDirectory())
Shinya Kitaoka 120a6e
    fatalError(string("Directory \"") + ::to_string(fp) +
Shinya Kitaoka 120a6e
               "\" not found or not readable");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath lRootDir    = fp + "toonzfarm";
Shinya Kitaoka 120a6e
  TFilePath logFilePath = lRootDir + "tcomposer.log";
Shinya Kitaoka 120a6e
  m_userLog             = new TUserLogAppend(logFilePath);
Shinya Kitaoka 120a6e
  string msg;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Initialize measure units
Shinya Kitaoka 120a6e
  Preferences::instance();                      // Loads standard (linear) units
Shinya Kitaoka 120a6e
  TMeasureManager::instance()->                 // Loads camera-related units
Shinya Kitaoka 120a6e
      addCameraMeasures(getCurrentCameraSize);  //
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePathSet fps = ToonzFolder::getProjectsFolders();
Shinya Kitaoka 120a6e
  TFilePathSet::iterator fpIt;
Shinya Kitaoka 120a6e
  for (fpIt = fps.begin(); fpIt != fps.end(); ++fpIt)
Shinya Kitaoka 120a6e
    TProjectManager::instance()->addProjectsRoot(*fpIt);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath libraryFolder = ToonzFolder::getLibraryFolder();
Shinya Kitaoka 120a6e
  TRasterImagePatternStrokeStyle::setRootDir(libraryFolder);
Shinya Kitaoka 120a6e
  TVectorImagePatternStrokeStyle::setRootDir(libraryFolder);
Shinya Kitaoka 120a6e
  TVectorBrushStyle::setRootDir(libraryFolder);
Shinya Kitaoka 120a6e
  TPalette::setRootDir(libraryFolder);
Shinya Kitaoka 120a6e
  TImageStyle::setLibraryDir(libraryFolder);
shun-iwasawa 9a8615
  TFilePath cacheRoot = ToonzFolder::getCacheRootFolder();
shun_iwasawa 7e52a2
  if (cacheRoot.isEmpty()) cacheRoot = TEnv::getStuffDir() + "cache";
Shinya Kitaoka 120a6e
  TImageCache::instance()->setRootDir(cacheRoot);
Shinya Kitaoka 120a6e
  // #endif
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TaskId       = QString::fromStdString(idq.getValue());
Shinya Kitaoka 120a6e
  string fdata = farmData.getValue();
Shinya Kitaoka 120a6e
  if (fdata.empty())
Shinya Kitaoka 120a6e
    UseRenderFarm = false;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    UseRenderFarm         = true;
Shinya Kitaoka 120a6e
    string::size_type pos = fdata.find('@');
Shinya Kitaoka 120a6e
    if (pos == string::npos)
Shinya Kitaoka 120a6e
      UseRenderFarm = false;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      FarmControllerPort = std::stoi(fdata.substr(0, pos));
Shinya Kitaoka 120a6e
      FarmControllerName = QString::fromStdString(fdata.substr(pos + 1));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (UseRenderFarm) {
Shinya Kitaoka 120a6e
    TFarmControllerFactory factory;
Shinya Kitaoka 120a6e
    factory.create(FarmControllerName, FarmControllerPort, &FarmController);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (!PluginLoader::load_entries("")) app.processEvents();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::pair<int, int=""> framePair(1, 0);</int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    Tiio::defineStd();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    initImageIo();
Shinya Kitaoka 120a6e
    Tiio::defineStd();
Shinya Kitaoka 120a6e
    initSoundIo();
Shinya Kitaoka 120a6e
    initStdFx();
Shinya Kitaoka 120a6e
    initColorFx();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    loadShaderInterfaces(ToonzFolder::getLibraryFolder() +
Shinya Kitaoka 120a6e
                         TFilePath("shaders"));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //#endif
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TFilePath srcFilePath = srcName.getValue();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      srcFilePath = TSystem::toLocalPath(srcFilePath);
Shinya Kitaoka 120a6e
    } catch (...) {
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //---------------------------------------------------------
Shinya Kitaoka 120a6e
    msg = "Loading " + srcFilePath.getName();
Shinya Kitaoka 120a6e
    cout << endl << msg << endl;
Shinya Kitaoka 120a6e
    m_userLog->info(msg);
Shinya Kitaoka 120a6e
    TProjectManager *pm = TProjectManager::instance();
Shinya Kitaoka 120a6e
    // pm->enableTabMode(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TProjectP project = pm->loadSceneProject(srcFilePath);
Shinya Kitaoka 120a6e
    if (!project) {
Shinya Kitaoka 120a6e
      msg = "Couldn't find the project";  //+ project->getName().getName();
Shinya Kitaoka 120a6e
      cerr << msg << endl;
Shinya Kitaoka 120a6e
      m_userLog->error(msg);
Shinya Kitaoka 120a6e
      return -2;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    msg = "project: " + project->getName().getName();
Shinya Kitaoka 120a6e
    cout << msg << endl;
Shinya Kitaoka 120a6e
    m_userLog->info(msg);
Shinya Kitaoka 120a6e
    // pm->setCurrentProject(project, false); // false => temporaneamente
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    Sw1.start();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!TSystem::doesExistFileOrLevel(srcFilePath)) return false;
Shinya Kitaoka 120a6e
    ToonzScene *scene = new ToonzScene();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TImageStyle::setCurrentScene(scene);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      Sw2.start();
Shinya Kitaoka 120a6e
      scene->load(srcFilePath);
Shinya Kitaoka 120a6e
      Sw2.stop();
Shinya Kitaoka 120a6e
    } catch (TException &e) {
Shinya Kitaoka 120a6e
      cout << ::to_string(e.getMessage()) << endl;
Shinya Kitaoka 120a6e
      m_userLog->error(::to_string(e.getMessage()));
Shinya Kitaoka 120a6e
      return -2;
Shinya Kitaoka 120a6e
    } catch (...) {
Shinya Kitaoka 120a6e
      string msg;
Shinya Kitaoka 120a6e
      msg = "There were problems loading the scene " +
Shinya Kitaoka 120a6e
            ::to_string(srcFilePath) + ".\n Some files may be missing.";
Shinya Kitaoka 120a6e
      cout << msg << endl;
Shinya Kitaoka 120a6e
      m_userLog->error(msg);
Shinya Kitaoka 120a6e
      // return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    msg = "scene loaded";
Shinya Kitaoka 120a6e
    cout << "scene loaded" << endl;
Shinya Kitaoka 120a6e
    m_userLog->info(msg);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TFilePath dstFilePath;
Shinya Kitaoka 120a6e
    if (dstName.isSelected())
Shinya Kitaoka 120a6e
      dstFilePath = dstName.getValue();
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      dstFilePath = scene->getProperties()->getOutputProperties()->getPath();
Shinya Kitaoka 120a6e
      if (dstFilePath == TFilePath())
Shinya Kitaoka 120a6e
        dstFilePath = TFilePath("+outputs") + "$scenename.tif";
Shinya Kitaoka 120a6e
      else if (dstFilePath.getName() == "")
Shinya Kitaoka 120a6e
        dstFilePath = (dstFilePath.getParentDir() + scene->getSceneName())
Shinya Kitaoka 120a6e
                          .withType(dstFilePath.getType());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    dstFilePath = scene->decodeFilePath(dstFilePath);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //---------------------------------------------------------
Shinya Kitaoka 120a6e
    msg = "Generating " + dstFilePath.getName();
Shinya Kitaoka 120a6e
    cout << endl << "Generating " << dstFilePath << endl << endl;
Shinya Kitaoka 120a6e
    m_userLog->info(msg);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TFilePath theDstFilePath = dstFilePath;
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      theDstFilePath = TSystem::toLocalPath(dstFilePath);
Shinya Kitaoka 120a6e
    } catch (...) {
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int r0 = -1, r1 = -1, step = 1, shrink = 1;
Shinya Kitaoka 120a6e
    TOutputProperties *outProp = scene->getProperties()->getOutputProperties();
Shinya Kitaoka 120a6e
    int scene_from, scene_to, scene_step;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    outProp->getRange(scene_from, scene_to, scene_step);
Shinya Kitaoka 120a6e
    int scene_shrink = outProp->getRenderSettings().m_shrinkX;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (scene_from == 0 && scene_to == -1) {
Shinya Kitaoka 120a6e
      scene_from = 1;
Shinya Kitaoka 120a6e
      scene_to   = scene->getFrameCount();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      scene_from++;
Shinya Kitaoka 120a6e
      scene_to++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (range.isSelected()) {
Shinya Kitaoka 120a6e
      r0 = range.getFrom();
Shinya Kitaoka 120a6e
      r1 = range.getTo();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      r0 = scene_from;
Shinya Kitaoka 120a6e
      r1 = scene_to;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (stepOpt.isSelected())
Shinya Kitaoka 120a6e
      step = stepOpt.getValue();
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      step = scene_step;
Shinya Kitaoka 120a6e
    if (shrinkOpt.isSelected())
Shinya Kitaoka 120a6e
      shrink = shrinkOpt.getValue();
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      shrink = scene_shrink;
Shinya Kitaoka 120a6e
    if (multimedia.isSelected())
Shinya Kitaoka 120a6e
      scene->getProperties()->getOutputProperties()->setMultimediaRendering(
Shinya Kitaoka 120a6e
          multimedia.getValue());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Retrieve Thread count
Shinya Kitaoka 120a6e
    const int procCount = TSystem::getProcessorCount();
Shinya Kitaoka 120a6e
    int threadCount;
Shinya Kitaoka 120a6e
    const int threadCounts[3] = {1, procCount / 2, procCount};
Shinya Kitaoka 120a6e
    if (nthreads.isSelected()) {
Shinya Kitaoka 120a6e
      QString threadCountStr = QString::fromStdString(nthreads.getValue());
Shinya Kitaoka 120a6e
      threadCount            = (threadCountStr == "single")
Shinya Kitaoka 120a6e
                        ? threadCounts[0]
Shinya Kitaoka 120a6e
                        : (threadCountStr == "half")
Shinya Kitaoka 120a6e
                              ? threadCounts[1]
Shinya Kitaoka 120a6e
                              : (threadCountStr == "all")
Shinya Kitaoka 120a6e
                                    ? threadCounts[2]
Shinya Kitaoka 120a6e
                                    : threadCountStr.toInt();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (threadCount <= 0) {
Shinya Kitaoka 120a6e
        cout << "Qualifier 'nthreads': bad input" << endl;
Shinya Kitaoka 120a6e
        exit(1);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      int threadIndex = outProp->getThreadIndex();
Shinya Kitaoka 120a6e
      threadCount     = threadCounts[threadIndex];
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    threadCount = tcrop(1, procCount, threadCount);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Retrieve max tile size (raster granularity)
Shinya Kitaoka 120a6e
    int maxTileSize;
Shinya Kitaoka 120a6e
    const int maxTileSizes[4] = {
Shinya Kitaoka 120a6e
        (std::numeric_limits<int>::max)(), TOutputProperties::LargeVal,</int>
Shinya Kitaoka 120a6e
        TOutputProperties::MediumVal, TOutputProperties::SmallVal};
Shinya Kitaoka 120a6e
    if (tileSize.isSelected()) {
Shinya Kitaoka 120a6e
      QString tileSizeStr = QString::fromStdString(tileSize.getValue());
Shinya Kitaoka 120a6e
      maxTileSize         = (tileSizeStr == "none")
Shinya Kitaoka 120a6e
                        ? maxTileSizes[0]
Shinya Kitaoka 120a6e
                        : (tileSizeStr == "large")
Shinya Kitaoka 120a6e
                              ? maxTileSizes[1]
Shinya Kitaoka 120a6e
                              : (tileSizeStr == "medium")
Shinya Kitaoka 120a6e
                                    ? maxTileSizes[2]
Shinya Kitaoka 120a6e
                                    : (tileSizeStr == "small")
Shinya Kitaoka 120a6e
                                          ? maxTileSizes[3]
Shinya Kitaoka 120a6e
                                          : tileSizeStr.toInt();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (maxTileSize <= 0) {
Shinya Kitaoka 120a6e
        cout << "Qualifier 'maxtilesize': bad input" << endl;
Shinya Kitaoka 120a6e
        exit(1);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      int maxTileSizeIndex = outProp->getMaxTileSizeIndex();
Shinya Kitaoka 120a6e
      maxTileSize          = maxTileSizes[maxTileSizeIndex];
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_userLog->info("Threads count: " + std::to_string(threadCount));
Shinya Kitaoka 120a6e
    if (maxTileSize != (std::numeric_limits<int>::max)())</int>
Shinya Kitaoka 120a6e
      m_userLog->info("Render tile: " + std::to_string(maxTileSize));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Disable the Passive cache manager. It has no sense if it cannot write on
Shinya Kitaoka 120a6e
    // disk...
Shinya Kitaoka 120a6e
    // TCacheResourcePool::instance();   //Needs to be instanced before
Shinya Kitaoka 120a6e
    // TPassiveCacheManager...
Shinya Kitaoka 120a6e
    TPassiveCacheManager::instance()->setEnabled(false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#ifndef x64
Shinya Kitaoka 120a6e
    // On 32-bit architecture, there could be cases in which initialization
Shinya Kitaoka 120a6e
    // could alter the
Shinya Kitaoka 120a6e
    // FPU floating point control word. I've seen this happen when loading some
Shinya Kitaoka 120a6e
    // AVI coded (VFAPI),
Shinya Kitaoka 120a6e
    // where 80-bit internal precision was used instead of the standard 64-bit
Shinya Kitaoka 120a6e
    // (much faster and
Shinya Kitaoka 120a6e
    // sufficient - especially considering that x86 truncates to 64-bit
Shinya Kitaoka 120a6e
    // representation anyway).
Shinya Kitaoka 120a6e
    // IN ANY CASE, revert to the original control word.
Shinya Kitaoka 120a6e
    // In the x64 case these precision changes simply should not take place up
Shinya Kitaoka 120a6e
    // to _controlfp_s
Shinya Kitaoka 120a6e
    // documentation.
Shinya Kitaoka 120a6e
    _controlfp_s(0, fpWord, -1);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    framePair = generateMovie(scene, theDstFilePath, r0, r1, step, shrink,
Shinya Kitaoka 120a6e
                              threadCount, maxTileSize);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    Sw1.stop();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_userLog->info(
Shinya Kitaoka 120a6e
        "Raster Allocation Peak: " +
Shinya Kitaoka 120a6e
        std::to_string(TBigMemoryManager::instance()->getAllocationPeak()) +
Shinya Kitaoka 120a6e
        " KB");
Shinya Kitaoka 120a6e
    m_userLog->info(
Shinya Kitaoka 120a6e
        "Raster Allocation Mean: " +
Shinya Kitaoka 120a6e
        std::to_string(TBigMemoryManager::instance()->getAllocationMean()) +
Shinya Kitaoka 120a6e
        " KB");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    msg = "Compositing completed in " +
Shinya Kitaoka 120a6e
          ::to_string(Sw1.getTotalTime() / 1000.0, 2) + " seconds";
Shinya Kitaoka 120a6e
    string msg2 =
Shinya Kitaoka 120a6e
        "\n" + ::to_string(Sw2.getTotalTime() / 1000.0, 2) +
Shinya Kitaoka 120a6e
        " seconds spent on loading" + "\n" +
Shinya Kitaoka 120a6e
        ::to_string(TStopWatch::global(0).getTotalTime() / 1000.0, 2) +
Shinya Kitaoka 120a6e
        " seconds spent on saving" + "\n" +
Shinya Kitaoka 120a6e
        ::to_string(TStopWatch::global(8).getTotalTime() / 1000.0, 2) +
Shinya Kitaoka 120a6e
        " seconds spent on rendering" + "\n";
Shinya Kitaoka 120a6e
    cout << msg + msg2;
Shinya Kitaoka 120a6e
    m_userLog->info(msg + msg2);
Shinya Kitaoka 120a6e
    DVGui::info(QString::fromStdString(msg));
Shinya Kitaoka 120a6e
    TImageCache::instance()->clear(true);
Shinya Kitaoka 120a6e
  } catch (TException &e) {
shun-iwasawa 9a8615
    msg = "Untrapped exception: " + ::to_string(e.getMessage()),
shun-iwasawa 9a8615
    cout << msg << endl;
Shinya Kitaoka 120a6e
    m_userLog->error(msg);
Shinya Kitaoka 120a6e
    TImageCache::instance()->clear(true);
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
    cout << "Untrapped exception" << endl;
Shinya Kitaoka 120a6e
    m_userLog->error("Untrapped exception");
Shinya Kitaoka 120a6e
    TImageCache::instance()->clear(true);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (framePair.first != framePair.second) return -1;
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}