|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzFarm includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tfarmcontroller.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzLib includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshleveltypes.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tpalettehandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tscenehandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshlevelhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/sceneproperties.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/levelproperties.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/levelupdater.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/preferences.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzfolders.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzscene.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshchildlevel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tproject.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tcleanupper.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txsheet.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshcell.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshcolumn.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tlog.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/imagestyles.h"
|
|
shun-iwasawa |
22b8d4 |
#include "toonz/filepathproperties.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzBase includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tcli.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tenv.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tsystem.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstream.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstopwatch.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tthread.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tthreadmessage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "timagecache.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tiio_std.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tnzimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmsgcore.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpluginmanager.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpalette.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsimplecolorstyles.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Qt includes
|
|
Toshihiro Shimizu |
890ddd |
#include <qapplication></qapplication>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace TCli;
|
|
Toshihiro Shimizu |
890ddd |
using namespace std;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline ostream &operator<<(ostream &out, const wstring &w) {
|
|
Shinya Kitaoka |
120a6e |
return out << ::to_string(w);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline ostream &operator<<(ostream &out, const TFilePath &fp) {
|
|
Shinya Kitaoka |
120a6e |
return out << fp.getWideString();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
f39ea0 |
const char *rootVarName = "TOONZROOT";
|
|
shun-iwasawa |
f39ea0 |
const char *systemVarPrefix = "TOONZ";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
CleanupParameters GlobalParameters;
|
|
Toshihiro Shimizu |
890ddd |
TFilePath CurrentSettingsFile = TFilePath();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void loadSettings(const TFilePath &settingsFile, CleanupParameters *cp) {
|
|
Shinya Kitaoka |
120a6e |
if (CurrentSettingsFile ==
|
|
Shinya Kitaoka |
120a6e |
TFilePath()) // the parameters were global ...I store them
|
|
Shinya Kitaoka |
120a6e |
GlobalParameters.assign(cp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
CurrentSettingsFile = settingsFile;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TIStream *is = new TIStream(settingsFile);
|
|
Shinya Kitaoka |
120a6e |
int minor, major;
|
|
Shinya Kitaoka |
120a6e |
string tagName;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Extract file version if any
|
|
Shinya Kitaoka |
120a6e |
is->matchTag(tagName);
|
|
Shinya Kitaoka |
120a6e |
if (tagName == "version") {
|
|
Shinya Kitaoka |
120a6e |
*is >> major >> minor;
|
|
Shinya Kitaoka |
120a6e |
is->matchEndTag();
|
|
Shinya Kitaoka |
120a6e |
is->setVersion(VersionNumber(major, minor));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
delete is;
|
|
Shinya Kitaoka |
120a6e |
is = new TIStream(settingsFile);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
cp->loadData(*is, true);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
delete is;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void restoreGlobalSettings(CleanupParameters *cp) {
|
|
Shinya Kitaoka |
120a6e |
if (CurrentSettingsFile == TFilePath()) return; // already global!
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
cp->assign(&GlobalParameters);
|
|
Shinya Kitaoka |
120a6e |
CurrentSettingsFile = TFilePath();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
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 |
msg = "Application can't start:\n" + msg;
|
|
Shinya Kitaoka |
120a6e |
DVGui::error(QString::fromStdString(msg));
|
|
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 |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
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 |
// 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 |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void prepareToCleanup(TXshSimpleLevel *xl, TPalette *cleanupPalette) {
|
|
Shinya Kitaoka |
120a6e |
assert(xl->getScene());
|
|
Shinya Kitaoka |
120a6e |
if (xl->getProperties()->getSubsampling() != 1) {
|
|
Shinya Kitaoka |
120a6e |
xl->getProperties()->setSubsampling(1);
|
|
Shinya Kitaoka |
120a6e |
xl->invalidateFrames();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* int ltype = xl->getType();
|
|
Shinya Kitaoka |
120a6e |
if(ltype != TZP_XSHLEVEL)
|
|
Shinya Kitaoka |
120a6e |
xl->makeTlv(xl->getScene()->getDefaultParentDir(TZP_XSHLEVEL));
|
|
Shinya Kitaoka |
120a6e |
if(xl->getPalette()==0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
//PaletteController* pc = TApp::instance()->getPaletteController();
|
|
Shinya Kitaoka |
120a6e |
xl->setPalette(cleanupPalette);
|
|
Shinya Kitaoka |
120a6e |
//if(xl == TApp::instance()->getCurrentLevel()->getLevel())
|
|
Shinya Kitaoka |
120a6e |
// pc->getCurrentLevelPalette()->setPalette(xl->getPalette());
|
|
Shinya Kitaoka |
120a6e |
}*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
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 |
string FarmControllerName;
|
|
Toshihiro Shimizu |
890ddd |
int FarmControllerPort;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TFarmController *FarmController = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
string TaskId;
|
|
shun-iwasawa |
7f4819 |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// searchLevelsToCleanup
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// Restituisce l'elenco (ordinato per ordine alfabetico di nome)
|
|
Shinya Kitaoka |
120a6e |
// dei livelli TLV(con scannedPath)/TZI/OVL presenti nell'xsheet (o nei
|
|
Shinya Kitaoka |
120a6e |
// sottoxsheet)
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Shinya Kitaoka |
120a6e |
// se selectedOnly = true salta i livelli presenti nelle colonne senza
|
|
Shinya Kitaoka |
120a6e |
// "occhietto"
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void searchLevelsToCleanup(
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::pair<txshsimplelevel *,="" std::set<tframeid="">>> &levels,</std::pair<txshsimplelevel>
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh, bool selectedOnly) {
|
|
Shinya Kitaoka |
120a6e |
std::map<wstring, *="" txshsimplelevel=""> levelTable;</wstring,>
|
|
Shinya Kitaoka |
120a6e |
std::map<wstring, std::set<tframeid="">> framesTable;</wstring,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::set<txsheet *=""> visited;</txsheet>
|
|
Shinya Kitaoka |
120a6e |
std::vector<txsheet *=""> xsheets;</txsheet>
|
|
Shinya Kitaoka |
120a6e |
xsheets.push_back(xsh);
|
|
Shinya Kitaoka |
120a6e |
visited.insert(xsh);
|
|
Shinya Kitaoka |
120a6e |
while (!xsheets.empty()) {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = xsheets.back();
|
|
Shinya Kitaoka |
120a6e |
xsheets.pop_back();
|
|
Shinya Kitaoka |
120a6e |
for (int c = 0; c < xsh->getColumnCount(); c++) {
|
|
Shinya Kitaoka |
120a6e |
TXshColumn *column = xsh->getColumn(c);
|
|
Shinya Kitaoka |
120a6e |
if (!column || column->isEmpty()) continue;
|
|
Shinya Kitaoka |
120a6e |
// if(selectedOnly && !column->isPreviewVisible()) continue;
|
|
Shinya Kitaoka |
120a6e |
int r0 = 0, r1 = -1;
|
|
Shinya Kitaoka |
120a6e |
xsh->getCellRange(c, r0, r1);
|
|
Shinya Kitaoka |
120a6e |
for (int r = r0; r <= r1; r++) {
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = xsh->getCell(r, c);
|
|
Shinya Kitaoka |
120a6e |
if (cell.isEmpty()) continue;
|
|
Shinya Kitaoka |
120a6e |
if (TXshSimpleLevel *sl = cell.m_level->getSimpleLevel()) {
|
|
Shinya Kitaoka |
120a6e |
if (selectedOnly && !column->isPreviewVisible()) // pezza: se questo
|
|
Shinya Kitaoka |
120a6e |
// "if" veniva fatto
|
|
Shinya Kitaoka |
120a6e |
// sopra(riga
|
|
Shinya Kitaoka |
120a6e |
// commentata)
|
|
Shinya Kitaoka |
120a6e |
// quando si fa save della Scene alla fine della cleanuppata,
|
|
Shinya Kitaoka |
120a6e |
// venivano backuppate le tif non processate e cancellati gli
|
|
Shinya Kitaoka |
120a6e |
// originali!
|
|
Shinya Kitaoka |
120a6e |
// Deliri del levelUPdater; evito di mettere le mani in quel pattume.
|
|
Shinya Kitaoka |
120a6e |
// vinz
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
sl->setDirtyFlag(false);
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
int ltype = sl->getType();
|
|
Rozhuk Ivan |
823a31 |
if ((ltype == TZP_XSHLEVEL && sl->getScannedPath() != TFilePath()) ||
|
|
Shinya Kitaoka |
120a6e |
ltype == OVL_XSHLEVEL || ltype == TZI_XSHLEVEL) {
|
|
Shinya Kitaoka |
120a6e |
wstring levelName = sl->getName();
|
|
Shinya Kitaoka |
120a6e |
levelTable[levelName] = sl;
|
|
Shinya Kitaoka |
120a6e |
framesTable[levelName].insert(cell.m_frameId);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (TXshChildLevel *cl = cell.m_level->getChildLevel()) {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *subXsh = cl->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
if (visited.count(subXsh) == 0) {
|
|
Shinya Kitaoka |
120a6e |
visited.insert(subXsh);
|
|
Shinya Kitaoka |
120a6e |
xsheets.push_back(subXsh);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(levelTable.size() == framesTable.size());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (auto const &level : levelTable) {
|
|
Shinya Kitaoka |
120a6e |
auto const it = framesTable.find(level.first);
|
|
Shinya Kitaoka |
120a6e |
if (it == framesTable.end()) {
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
levels.push_back(std::make_pair(level.second, (*it).second));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*- CleanupDefaultパレットを追加する -*/
|
|
Campbell Barton |
8c6c57 |
static void addCleanupDefaultPalette(TXshSimpleLevel *sl) {
|
|
Shinya Kitaoka |
120a6e |
/*- 元となるパレットはStudioPaletteフォルダに置く -*/
|
|
Shinya Kitaoka |
120a6e |
TFilePath palettePath =
|
|
Shinya Kitaoka |
120a6e |
ToonzFolder::getStudioPaletteFolder() + "cleanup_default.tpl";
|
|
Shinya Kitaoka |
120a6e |
TFileStatus pfs(palettePath);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!pfs.doesExist() || !pfs.isReadable()) {
|
|
Shinya Kitaoka |
120a6e |
wcout << L"CleanupDefaultPalette file: " << palettePath.getWideString()
|
|
Shinya Kitaoka |
120a6e |
<< L" is not found!" << endl;
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TIStream is(palettePath);
|
|
Shinya Kitaoka |
120a6e |
if (!is) {
|
|
Shinya Kitaoka |
120a6e |
cout << "CleanupDefaultPalette file: failed to get TIStream" << endl;
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
string tagName;
|
|
Shinya Kitaoka |
120a6e |
if (!is.matchTag(tagName) || tagName != "palette") {
|
|
Shinya Kitaoka |
120a6e |
cout << "CleanupDefaultPalette file: This is not palette file" << endl;
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
string gname;
|
|
Shinya Kitaoka |
120a6e |
is.getTagParam("name", gname);
|
|
Shinya Kitaoka |
120a6e |
TPalette *defaultPalette = new TPalette();
|
|
Shinya Kitaoka |
120a6e |
defaultPalette->loadData(is);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
sl->getPalette()->setIsCleanupPalette(false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPalette::Page *dstPage = sl->getPalette()->getPage(0);
|
|
Shinya Kitaoka |
120a6e |
TPalette::Page *srcPage = defaultPalette->getPage(0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int srcIndexInPage = 0; srcIndexInPage < srcPage->getStyleCount();
|
|
Shinya Kitaoka |
120a6e |
srcIndexInPage++) {
|
|
Shinya Kitaoka |
120a6e |
int id = srcPage->getStyleId(srcIndexInPage);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool isUsedInCleanupPalette;
|
|
Shinya Kitaoka |
120a6e |
isUsedInCleanupPalette = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int dstIndexInPage = 0; dstIndexInPage < dstPage->getStyleCount();
|
|
Shinya Kitaoka |
120a6e |
dstIndexInPage++) {
|
|
Shinya Kitaoka |
120a6e |
if (dstPage->getStyleId(dstIndexInPage) == id) {
|
|
Shinya Kitaoka |
120a6e |
isUsedInCleanupPalette = true;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (isUsedInCleanupPalette)
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
int addedId = sl->getPalette()->addStyle(
|
|
Shinya Kitaoka |
120a6e |
srcPage->getStyle(srcIndexInPage)->clone());
|
|
Shinya Kitaoka |
120a6e |
dstPage->addStyle(addedId);
|
|
Shinya Kitaoka |
120a6e |
/*- StudioPalette由来のDefaultPaletteの場合、GrobalNameを消去する -*/
|
|
Shinya Kitaoka |
120a6e |
sl->getPalette()->getStyle(addedId)->setGlobalName(L"");
|
|
Shinya Kitaoka |
120a6e |
sl->getPalette()->getStyle(addedId)->setOriginalName(L"");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
delete defaultPalette;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// cleanupLevel
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// effettua il cleanup del livello. Se il livello e' un fullcolor
|
|
Toshihiro Shimizu |
890ddd |
// modifica tipo e parametri e crea la palette
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// se overwrite == false non fa il cleanup dei frames gia' cleanuppati
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void cleanupLevel(TXshSimpleLevel *xl, std::set<tframeid> fidsInXsheet,</tframeid>
|
|
Campbell Barton |
8c6c57 |
ToonzScene *scene, bool overwrite,
|
|
Campbell Barton |
8c6c57 |
TUserLogAppend &m_userLog) {
|
|
Shinya Kitaoka |
120a6e |
prepareToCleanup(xl, scene->getProperties()
|
|
Shinya Kitaoka |
120a6e |
->getCleanupParameters()
|
|
Shinya Kitaoka |
120a6e |
->m_cleanupPalette.getPointer());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TCleanupper *cl = TCleanupper::instance();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFilePath fp = scene->decodeFilePath(xl->getPath());
|
|
Shinya Kitaoka |
120a6e |
TSystem::touchParentDir(fp);
|
|
Shinya Kitaoka |
120a6e |
cout << "cleanupping " << xl->getName() << " path=" << fp << endl;
|
|
Shinya Kitaoka |
120a6e |
string info = "cleanupping " + ::to_string(xl->getPath());
|
|
Shinya Kitaoka |
120a6e |
LevelUpdater updater(xl);
|
|
Shinya Kitaoka |
120a6e |
m_userLog.info(info);
|
|
Shinya Kitaoka |
120a6e |
DVGui::info(QString::fromStdString(info));
|
|
Shinya Kitaoka |
120a6e |
bool firstImage = true;
|
|
Shinya Kitaoka |
120a6e |
for (auto const &fid : fidsInXsheet) {
|
|
Shinya Kitaoka |
120a6e |
cout << " " << fid << endl;
|
|
Shinya Kitaoka |
120a6e |
info = " " + fid.expand();
|
|
Shinya Kitaoka |
120a6e |
m_userLog.info(info);
|
|
Shinya Kitaoka |
120a6e |
int status = xl->getFrameStatus(fid);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (0 != (status & TXshSimpleLevel::Cleanupped) && !overwrite) {
|
|
Shinya Kitaoka |
120a6e |
cout << " skipped" << endl;
|
|
Shinya Kitaoka |
120a6e |
m_userLog.info(" skipped");
|
|
Shinya Kitaoka |
120a6e |
DVGui::info(QString("--skipped frame ") +
|
|
Shinya Kitaoka |
120a6e |
QString::fromStdString(fid.expand()));
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
shun-iwasawa |
76a039 |
CleanupParameters *params = scene->getProperties()->getCleanupParameters();
|
|
shun-iwasawa |
76a039 |
// if lines are not processed, obtain the original sampled image
|
|
shun-iwasawa |
76a039 |
bool toBeLineProcessed = params->m_lineProcessingMode != lpNone;
|
|
shun-iwasawa |
76a039 |
TRasterImageP original = xl->getFrameToCleanup(fid, toBeLineProcessed);
|
|
Shinya Kitaoka |
120a6e |
if (!original) {
|
|
Shinya Kitaoka |
120a6e |
string err = " *error* missed frame";
|
|
Shinya Kitaoka |
120a6e |
m_userLog.error(err);
|
|
Shinya Kitaoka |
120a6e |
cout << err << endl;
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (params->m_lineProcessingMode == lpNone) {
|
|
shun-iwasawa |
76a039 |
TRasterImageP ri(original);
|
|
shun-iwasawa |
76a039 |
/*if (params->m_autocenterType == CleanupTypes::AUTOCENTER_NONE)
|
|
Shinya Kitaoka |
120a6e |
ri = original;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
bool autocentered;
|
|
Shinya Kitaoka |
120a6e |
ri = cl->autocenterOnly(original, false, autocentered);
|
|
Shinya Kitaoka |
120a6e |
if (!autocentered) {
|
|
Shinya Kitaoka |
120a6e |
m_userLog.error("The autocentering failed on the current drawing.");
|
|
Shinya Kitaoka |
120a6e |
cout << "The autocentering failed on the current drawing." << endl;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
shun-iwasawa |
76a039 |
}*/
|
|
shun-iwasawa |
76a039 |
cl->process(original, false, ri, false, true, true, nullptr,
|
|
shun-iwasawa |
76a039 |
ri->getRaster());
|
|
Shinya Kitaoka |
120a6e |
updater.update(fid, ri);
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
shun-iwasawa |
e0fcf9 |
// Obtain the source dpi. Changed it to be done once at the first frame of
|
|
shun-iwasawa |
e0fcf9 |
// each level in order to avoid the following problem:
|
|
shun-iwasawa |
e0fcf9 |
// If the original raster level has no dpi (such as TGA images), obtaining
|
|
shun-iwasawa |
e0fcf9 |
// dpi in every frame causes dpi mismatch between the first frame and the
|
|
shun-iwasawa |
e0fcf9 |
// following frames, since the value
|
|
shun-iwasawa |
e0fcf9 |
// TXshSimpleLevel::m_properties->getDpi() will be changed to the
|
|
shun-iwasawa |
e0fcf9 |
// dpi of cleanup camera (= TLV's dpi) after finishing the first frame.
|
|
shun-iwasawa |
e0fcf9 |
if (firstImage) {
|
|
shun-iwasawa |
e0fcf9 |
TPointD dpi;
|
|
shun-iwasawa |
e0fcf9 |
original->getDpi(dpi.x, dpi.y);
|
|
shun-iwasawa |
e0fcf9 |
if (dpi.x == 0 && dpi.y == 0) dpi = xl->getProperties()->getDpi();
|
|
shun-iwasawa |
e0fcf9 |
cl->setSourceDpi(dpi);
|
|
shun-iwasawa |
e0fcf9 |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
CleanupPreprocessedImage *cpi;
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TRasterImageP resampledImage;
|
|
Shinya Kitaoka |
120a6e |
cpi = cl->process(original, firstImage, resampledImage);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TToonzImageP timage = cl->finalize(cpi, true);
|
|
Shinya Kitaoka |
120a6e |
TPointD dpi(0, 0);
|
|
Shinya Kitaoka |
120a6e |
timage->getDpi(dpi.x, dpi.y);
|
|
Shinya Kitaoka |
120a6e |
if (dpi.x != 0 && dpi.y != 0) xl->getProperties()->setDpi(dpi);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (firstImage) addCleanupDefaultPalette(xl);
|
|
Shinya Kitaoka |
120a6e |
firstImage = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
timage->setPalette(xl->getPalette());
|
|
Shinya Kitaoka |
120a6e |
xl->setFrameStatus(fid, status | TXshSimpleLevel::Cleanupped);
|
|
Shinya Kitaoka |
120a6e |
xl->setFrame(fid, timage);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
updater.update(fid, timage);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- 1フレーム終わったら、そのフレームのキャッシュは消す -*/
|
|
Shinya Kitaoka |
120a6e |
xl->invalidateFrame(fid);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
delete cpi;
|
|
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 |
// usage: tcleanup filename.tnz [-selected][-overwrite]
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int main(int argc, char *argv[]) {
|
|
Shinya Kitaoka |
120a6e |
QApplication app(argc, argv);
|
|
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 |
86aa7e |
TEnv::setApplicationFileName(argv[0]);
|
|
shun-iwasawa |
7f4819 |
|
|
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 |
|
|
Shinya Kitaoka |
120a6e |
TSystem::hasMainLoop(false);
|
|
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 |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
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("");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFilePath fproot = TEnv::getStuffDir();
|
|
Shinya Kitaoka |
120a6e |
if (fproot == TFilePath())
|
|
Shinya Kitaoka |
120a6e |
fatalError(string("Undefined: \"") + ::to_string(TEnv::getRootVarPath()) +
|
|
Shinya Kitaoka |
120a6e |
"\"");
|
|
Shinya Kitaoka |
120a6e |
if (!TFileStatus(fproot).isDirectory())
|
|
Shinya Kitaoka |
120a6e |
fatalError(string("Directory \"") + ::to_string(fproot) +
|
|
Shinya Kitaoka |
120a6e |
"\" not found or not readable");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFilePath lRootDir = TEnv::getStuffDir() + "toonzfarm";
|
|
Shinya Kitaoka |
120a6e |
TFilePath logFilePath = lRootDir + "tcleanup.log";
|
|
Shinya Kitaoka |
120a6e |
TUserLogAppend m_userLog(logFilePath);
|
|
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 |
TPalette::setRootDir(libraryFolder);
|
|
Shinya Kitaoka |
120a6e |
TImageStyle::setLibraryDir(libraryFolder);
|
|
shun-iwasawa |
7f4819 |
TFilePath cacheRoot = ToonzFolder::getCacheRootFolder();
|
|
Shinya Kitaoka |
120a6e |
if (cacheRoot.isEmpty()) cacheRoot = TEnv::getStuffDir() + "cache";
|
|
Shinya Kitaoka |
120a6e |
TImageCache::instance()->setRootDir(cacheRoot);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FilePathArgument srcName("tnzFile", "Scene file");
|
|
Shinya Kitaoka |
120a6e |
SimpleQualifier selectedOnlyOption("-onlyvisible", "Selected column only");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
SimpleQualifier overwriteAllOption("-overwriteAll",
|
|
Shinya Kitaoka |
120a6e |
"Overwrite all already cleanupped frames");
|
|
Shinya Kitaoka |
120a6e |
SimpleQualifier overwriteNoPaintOption(
|
|
Shinya Kitaoka |
120a6e |
"-overwriteNoPaint",
|
|
Shinya Kitaoka |
120a6e |
"Overwrite only no-paint levels of already cleanupped frames");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
StringQualifier farmData("-farm data", "TFarm Controller");
|
|
Shinya Kitaoka |
120a6e |
StringQualifier idq("-id n", "id");
|
|
Shinya Kitaoka |
120a6e |
StringQualifier tmsg("-tmsg n", "Internal use only");
|
|
Shinya Kitaoka |
120a6e |
Usage usage(argv[0]);
|
|
Shinya Kitaoka |
120a6e |
usage.add(srcName + selectedOnlyOption + overwriteAllOption +
|
|
Shinya Kitaoka |
120a6e |
overwriteNoPaintOption + farmData + idq + tmsg);
|
|
Shinya Kitaoka |
120a6e |
if (!usage.parse(argc, argv)) exit(1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TaskId = 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 = 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(QString::fromStdString(FarmControllerName),
|
|
Shinya Kitaoka |
120a6e |
FarmControllerPort, &FarmController);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- 画像Read/Writeの関数を登録 -*/
|
|
Shinya Kitaoka |
120a6e |
initImageIo();
|
|
Shinya Kitaoka |
120a6e |
Tiio::defineStd();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- プロジェクトのロード -*/
|
|
Shinya Kitaoka |
120a6e |
TProjectManager *pm = TProjectManager::instance();
|
|
Shinya Kitaoka |
120a6e |
TProjectP project = pm->loadSceneProject(srcName);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!project) {
|
|
Shinya Kitaoka |
120a6e |
string err = "Couldn't find the project" + project->getName().getName();
|
|
Shinya Kitaoka |
120a6e |
m_userLog.error(err);
|
|
Shinya Kitaoka |
120a6e |
cerr << err << endl;
|
|
Shinya Kitaoka |
120a6e |
return -2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cout << "project:" << project->getName() << endl;
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
22b8d4 |
// update TFilePath condition on loading the current project
|
|
shun-iwasawa |
22b8d4 |
FilePathProperties *fpProp = project->getFilePathProperties();
|
|
shun-iwasawa |
22b8d4 |
TFilePath::setFilePathProperties(fpProp->useStandard(),
|
|
shun-iwasawa |
22b8d4 |
fpProp->acceptNonAlphabetSuffix(),
|
|
shun-iwasawa |
22b8d4 |
fpProp->letterCountForSuffix());
|
|
shun-iwasawa |
22b8d4 |
|
|
Shinya Kitaoka |
120a6e |
TFilePath fp = srcName;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- CLNファイルを直接指定した場合 -*/
|
|
Shinya Kitaoka |
120a6e |
bool sourceFileIsCleanupSetting = (fp.getType() == "cln");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool selectedOnly = selectedOnlyOption;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ToonzScene *scene = new ToonzScene();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TImageStyle::setCurrentScene(scene);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- シーンファイルパスを入力した場合 -*/
|
|
Shinya Kitaoka |
120a6e |
if (!sourceFileIsCleanupSetting) {
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
scene->loadNoResources(fp);
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
string err = "can't read " + fp.getName();
|
|
Shinya Kitaoka |
120a6e |
m_userLog.error(err);
|
|
Shinya Kitaoka |
120a6e |
cerr << "can't read " << fp << endl;
|
|
Shinya Kitaoka |
120a6e |
TImageCache::instance()->clear(true);
|
|
Shinya Kitaoka |
120a6e |
return -3;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*-- CleanupSettingsファイルパスを直接入力した場合 --*/
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
shun_iwasawa |
4dbfbc |
TProjectManager *pm = TProjectManager::instance();
|
|
shun_iwasawa |
4dbfbc |
TProjectP sceneProject = pm->loadSceneProject(fp);
|
|
shun_iwasawa |
4dbfbc |
if (!sceneProject) {
|
|
shun_iwasawa |
4dbfbc |
cerr << "can't open project." << endl;
|
|
shun_iwasawa |
4dbfbc |
return -3;
|
|
shun_iwasawa |
4dbfbc |
}
|
|
shun_iwasawa |
4dbfbc |
scene->setProject(sceneProject.getPointer());
|
|
shun_iwasawa |
4dbfbc |
|
|
Shinya Kitaoka |
120a6e |
/*- CleanupSettingsファイルに対応するTIFファイルが有るかチェック -*/
|
|
Shinya Kitaoka |
120a6e |
TFilePath tifImagePath = fp.withType("tif");
|
|
Shinya Kitaoka |
120a6e |
std::wcout << L"tifImagePath : " << tifImagePath.getWideString()
|
|
Shinya Kitaoka |
120a6e |
<< std::endl;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-
|
|
Shinya Kitaoka |
120a6e |
* 無ければ、連番画像がソースである可能性がある。tifImagePathを連番に差し替える
|
|
Shinya Kitaoka |
120a6e |
* -*/
|
|
Shinya Kitaoka |
120a6e |
if (!TFileStatus(tifImagePath).doesExist()) {
|
|
Shinya Kitaoka |
120a6e |
tifImagePath =
|
|
Shinya Kitaoka |
120a6e |
tifImagePath.getParentDir() + (tifImagePath.getName() + "..tif");
|
|
Shinya Kitaoka |
120a6e |
std::wcout << "change the source path to : "
|
|
Shinya Kitaoka |
120a6e |
<< tifImagePath.getWideString() << std::endl;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
std::cout << "tif single image found" << std::endl;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- シーンファイルに対象のTIFファイルをロード -*/
|
|
Shinya Kitaoka |
120a6e |
TXshLevel *xl = scene->loadLevel(tifImagePath);
|
|
Shinya Kitaoka |
120a6e |
if (!xl) {
|
|
Shinya Kitaoka |
120a6e |
std::cout << "failed to load level" << std::endl;
|
|
Shinya Kitaoka |
120a6e |
throw TException("Failed to load level.");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
std::vector<tframeid> dummy;</tframeid>
|
|
Shinya Kitaoka |
120a6e |
int frameLength = scene->getXsheet()->exposeLevel(0, 0, xl, dummy);
|
|
Shinya Kitaoka |
120a6e |
std::cout << "expose done. frameLength : " << frameLength << std::endl;
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
cerr << "can't read Cleanup Settings file " << fp << endl;
|
|
Shinya Kitaoka |
120a6e |
TImageCache::instance()->clear(true);
|
|
Shinya Kitaoka |
120a6e |
return -3;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Levels contiene i livelli e i rispettivi frames prsenti nell'xsheet.
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::pair<txshsimplelevel *,="" std::set<tframeid="">>> levels;</std::pair<txshsimplelevel>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- XsheetからCleanupするLevelのリストを得る -*/
|
|
Shinya Kitaoka |
120a6e |
searchLevelsToCleanup(levels, scene->getXsheet(), selectedOnly);
|
|
Shinya Kitaoka |
120a6e |
TSceneProperties *sprop = scene->getProperties();
|
|
Shinya Kitaoka |
120a6e |
CleanupParameters *params = scene->getProperties()->getCleanupParameters();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)levels.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
bool overwrite = overwriteAllOption;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *xl = levels[i].first->getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
if (!xl) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- CLNファイルパスを取得 -*/
|
|
Shinya Kitaoka |
120a6e |
TFilePath settingsFile =
|
|
Shinya Kitaoka |
120a6e |
xl->getScannedPath().isEmpty() ? xl->getPath() : xl->getScannedPath();
|
|
Shinya Kitaoka |
120a6e |
settingsFile =
|
|
Shinya Kitaoka |
120a6e |
scene->decodeFilePath(settingsFile).withNoFrame().withType("cln");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- CLNファイルがあればそれを用いる。無ければGlobal設定を読み込む -*/
|
|
Shinya Kitaoka |
120a6e |
// TFilePath settingsFile =
|
|
Shinya Kitaoka |
120a6e |
// scene->decodeFilePath(xl->getPath()).withNoFrame().withType("cln");
|
|
Shinya Kitaoka |
120a6e |
if (TFileStatus(settingsFile).doesExist())
|
|
Shinya Kitaoka |
120a6e |
loadSettings(settingsFile, params);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
restoreGlobalSettings(params);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TCleanupper::instance()->setParameters(params);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool lineProcessing = (params->m_lineProcessingMode != lpNone);
|
|
Shinya Kitaoka |
120a6e |
TFilePath tmp = params->getPath(scene);
|
|
Shinya Kitaoka |
120a6e |
int ltype = xl->getType();
|
|
Shinya Kitaoka |
120a6e |
assert(ltype == TZP_XSHLEVEL || ltype == TZI_XSHLEVEL ||
|
|
Shinya Kitaoka |
120a6e |
ltype == OVL_XSHLEVEL);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// target path
|
|
Shinya Kitaoka |
120a6e |
TFilePath targetPath = xl->getPath();
|
|
Shinya Kitaoka |
120a6e |
if (ltype != TZP_XSHLEVEL) {
|
|
Shinya Kitaoka |
120a6e |
if (lineProcessing)
|
|
Shinya Kitaoka |
120a6e |
targetPath =
|
|
Shinya Kitaoka |
120a6e |
targetPath
|
|
Shinya Kitaoka |
120a6e |
.withParentDir(params->getPath(
|
|
Shinya Kitaoka |
120a6e |
scene)) // scene->getDefaultParentDir(TZP_XSHLEVEL))
|
|
Shinya Kitaoka |
120a6e |
.withNoFrame()
|
|
Shinya Kitaoka |
120a6e |
.withType("tlv");
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
targetPath = targetPath.withParentDir(params->getPath(
|
|
Shinya Kitaoka |
120a6e |
scene)); // scene->getDefaultParentDir(TZP_XSHLEVEL));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
targetPath = targetPath.withParentDir(params->getPath(
|
|
Shinya Kitaoka |
120a6e |
scene)); // scene->getDefaultParentDir(TZP_XSHLEVEL));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- NoPaintを作る設定のとき、NoPaintの方だけにOverwriteするようにする -*/
|
|
Shinya Kitaoka |
120a6e |
bool isReCleanup;
|
|
Shinya Kitaoka |
120a6e |
isReCleanup = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- 再Cleanupのときにパスを元に戻すために用いる -*/
|
|
Shinya Kitaoka |
120a6e |
TFilePath originalLevelPath = TFilePath();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFilePath actualTargetPath = scene->decodeFilePath(targetPath);
|
|
Shinya Kitaoka |
120a6e |
/*- すでにLevelがある場合 -*/
|
|
Shinya Kitaoka |
120a6e |
if (TSystem::doesExistFileOrLevel(actualTargetPath) &&
|
|
Shinya Kitaoka |
120a6e |
Preferences::instance()->isSaveUnpaintedInCleanupEnable() &&
|
|
Shinya Kitaoka |
120a6e |
overwriteNoPaintOption) {
|
|
Shinya Kitaoka |
120a6e |
overwrite = true;
|
|
Shinya Kitaoka |
120a6e |
originalLevelPath = scene->codeFilePath(targetPath);
|
|
Shinya Kitaoka |
120a6e |
/*- パスを書き換え、再Cleanupのフラグを立てる -*/
|
|
Shinya Kitaoka |
120a6e |
isReCleanup = true;
|
|
Shinya Kitaoka |
120a6e |
/*- nopaintフォルダの作成 -*/
|
|
Shinya Kitaoka |
120a6e |
TFilePath nopaintDir = targetPath.getParentDir() + "nopaint";
|
|
Shinya Kitaoka |
120a6e |
if (!TFileStatus(nopaintDir).doesExist()) {
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
TSystem::mkDir(nopaintDir);
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*- 保存先のパスをnopaintの方にする -*/
|
|
Shinya Kitaoka |
120a6e |
targetPath =
|
|
Shinya Kitaoka |
120a6e |
targetPath.getParentDir() + "nopaint\\" +
|
|
Shinya Kitaoka |
120a6e |
TFilePath(targetPath.getName() + "_np." + targetPath.getType());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
std::wcout << L"targetPath = " << targetPath.getWideString() << std::endl;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (lineProcessing) {
|
|
Shinya Kitaoka |
120a6e |
if (ltype != TZP_XSHLEVEL) {
|
|
Shinya Kitaoka |
120a6e |
xl->makeTlv(targetPath);
|
|
Shinya Kitaoka |
120a6e |
} else if (targetPath != xl->getPath()) {
|
|
Shinya Kitaoka |
120a6e |
xl->setPath(targetPath, false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
xl->setPalette(
|
|
Shinya Kitaoka |
120a6e |
TCleanupper::instance()->createToonzPaletteFromCleanupPalette());
|
|
Shinya Kitaoka |
120a6e |
} else if (!params->getPath(scene).isEmpty()) {
|
|
Shinya Kitaoka |
120a6e |
xl->setScannedPath(xl->getPath());
|
|
Shinya Kitaoka |
120a6e |
xl->setPath(scene->codeFilePath(targetPath), false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::set<tframeid> fidsInXsheet = levels[i].second;</tframeid>
|
|
Shinya Kitaoka |
120a6e |
assert(fidsInXsheet.size() > 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
xl->load();
|
|
Shinya Kitaoka |
120a6e |
cleanupLevel(xl, fidsInXsheet, scene, overwrite, m_userLog);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- Cleanup完了後、Nopaintをnopaintフォルダに保存する -*/
|
|
Shinya Kitaoka |
120a6e |
if (Preferences::instance()->isSaveUnpaintedInCleanupEnable() &&
|
|
Shinya Kitaoka |
120a6e |
!isReCleanup) /*-- 再Cleanupのときはnopaintを作らない --*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
/*- nopaintフォルダの作成 -*/
|
|
Shinya Kitaoka |
120a6e |
TFilePath nopaintDir = actualTargetPath.getParentDir() + "nopaint";
|
|
Shinya Kitaoka |
120a6e |
if (!TFileStatus(nopaintDir).doesExist()) {
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
TSystem::mkDir(nopaintDir);
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
string err = "Can't make directory " + nopaintDir.getName();
|
|
Shinya Kitaoka |
120a6e |
m_userLog.error(err);
|
|
Shinya Kitaoka |
120a6e |
cerr << "Can't make directory" << endl;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Se sono nell'ultimo frame del livello salvo il livello cleanuppato
|
|
Shinya Kitaoka |
120a6e |
// in un file chiamato nome-unpainted (file di backup del cleanup).
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- 保存先 -*/
|
|
Shinya Kitaoka |
120a6e |
TFilePath unpaintedLevelPath =
|
|
Shinya Kitaoka |
120a6e |
actualTargetPath.getParentDir() + "nopaint\\" +
|
|
Shinya Kitaoka |
120a6e |
TFilePath(targetPath.getName() + "_np." + targetPath.getType());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (TFileStatus(actualTargetPath).doesExist() &&
|
|
Shinya Kitaoka |
120a6e |
(!TFileStatus(unpaintedLevelPath).doesExist() ||
|
|
Shinya Kitaoka |
120a6e |
overwriteAllOption) /*- 全て上書きなら既存のNoPaintに上書きする -*/
|
|
Shinya Kitaoka |
120a6e |
&& xl) {
|
|
Shinya Kitaoka |
120a6e |
/*- GUI上でCleanupするときと同様に、Cleanup結果をコピーして作る -*/
|
|
Shinya Kitaoka |
120a6e |
TSystem::copyFile(unpaintedLevelPath, actualTargetPath);
|
|
Shinya Kitaoka |
120a6e |
/*- パレットのコピー -*/
|
|
Shinya Kitaoka |
120a6e |
TFilePath levelPalettePath =
|
|
Shinya Kitaoka |
120a6e |
actualTargetPath.getParentDir() +
|
|
Shinya Kitaoka |
120a6e |
TFilePath(actualTargetPath.getName() + ".tpl");
|
|
Shinya Kitaoka |
120a6e |
TFilePath unpaintedLevelPalettePath =
|
|
Shinya Kitaoka |
120a6e |
levelPalettePath.getParentDir() + "nopaint\\" +
|
|
Shinya Kitaoka |
120a6e |
TFilePath(levelPalettePath.getName() + "_np." +
|
|
Shinya Kitaoka |
120a6e |
levelPalettePath.getType());
|
|
Shinya Kitaoka |
120a6e |
TSystem::copyFile(unpaintedLevelPalettePath, levelPalettePath);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*--
|
|
Shinya Kitaoka |
120a6e |
再Cleanupの場合はXsheet上のパスをオリジナルのもの(NoPaintでないもの)に戻す
|
|
Shinya Kitaoka |
120a6e |
--*/
|
|
Shinya Kitaoka |
120a6e |
else if (isReCleanup) {
|
|
Shinya Kitaoka |
120a6e |
xl->setPath(originalLevelPath);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- CleanupParamをGrobalに戻す -*/
|
|
Shinya Kitaoka |
120a6e |
restoreGlobalSettings(params);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- CleanupSettingsからCleanupを行った場合はシーンの保存は行わない -*/
|
|
Shinya Kitaoka |
120a6e |
if (sourceFileIsCleanupSetting) {
|
|
Shinya Kitaoka |
120a6e |
std::cout << "Cleanup from Setting file completed" << std::endl;
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
wstring wInfo = L"updating scene " + scene->getSceneName();
|
|
Shinya Kitaoka |
120a6e |
QString qInfo_ = QString::fromStdWString(wInfo);
|
|
Shinya Kitaoka |
120a6e |
string info = qInfo_.toStdString();
|
|
Shinya Kitaoka |
120a6e |
m_userLog.info(info);
|
|
Shinya Kitaoka |
120a6e |
cout << "updating scene " << scene->getSceneName() << endl;
|
|
Shinya Kitaoka |
120a6e |
/*- シーンを上書き保存 -*/
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
scene->save(fp);
|
|
Shinya Kitaoka |
120a6e |
TImageCache::instance()->clear(true);
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
wstring wErr = L"Can't save scene " + fp.getWideName();
|
|
Shinya Kitaoka |
120a6e |
QString qErr = QString::fromStdWString(wErr);
|
|
Shinya Kitaoka |
120a6e |
string err = qErr.toStdString();
|
|
Shinya Kitaoka |
120a6e |
m_userLog.error(err);
|
|
Shinya Kitaoka |
120a6e |
cerr << "Can't save scene" << endl;
|
|
Shinya Kitaoka |
120a6e |
TImageCache::instance()->clear(true);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
DVGui::info("Cleanup Done.");
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|