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