void TSystem::renameFileOrLevel_throw(const TFilePath &dst, const TFilePath &src, bool renamePalette) { if (renamePalette && ((src.getType() == "tlv") || (src.getType() == "tzp") || (src.getType() == "tzu"))) { // Special case: since renames cannot be 'grouped' in the UI, palettes are // automatically // renamed here if required const char *type = (src.getType() == "tlv") ? "tpl" : "plt"; TFilePath srcpltname(src.withNoFrame().withType(type)); TFilePath dstpltname(dst.withNoFrame().withType(type)); if (TSystem::doesExistFileOrLevel(src) && TSystem::doesExistFileOrLevel(srcpltname)) TSystem::renameFile(dstpltname, srcpltname, false); } if (src.isLevelName()) { TFilePathSet files; files = TSystem::readDirectory(src.getParentDir(), false); for (TFilePathSet::iterator it = files.begin(); it != files.end(); it++) { if (it->getLevelName() == src.getLevelName()) { TFilePath src1 = *it; TFilePath dst1 = dst.withFrame(it->getFrame()); TSystem::renameFile(dst1, src1); } } } else TSystem::renameFile(dst, src); }
void StudioPaletteTreeViewer::startDragDrop() { TRepetitionGuard guard; if (!guard.hasLock()) return; QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; QList<QUrl> urls; QList<QTreeWidgetItem *> items = selectedItems(); int i; for (i = 0; i < items.size(); i++) { // Sposto solo le palette. TFilePath path = getItemPath(items[i]); if (!path.isEmpty() && (path.getType() == "tpl" || path.getType() == "pli" || path.getType() == "tlv" || path.getType() == "tnz")) urls.append(pathToUrl(path)); } if (urls.isEmpty()) return; mimeData->setUrls(urls); drag->setMimeData(mimeData); Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction); viewport()->update(); }
void RenderCommand::doRender(bool isPreview) { bool isWritable = true; bool isMultiFrame; /*-- 初期化処理。フレーム範囲の計算や、Renderの場合はOutputSettingsから保存先パスも作る --*/ if (!init(isPreview)) return; if (m_fp.getDots() == ".") { isMultiFrame = false; TFileStatus fs(m_fp); if (fs.doesExist()) isWritable = fs.isWritable(); } else { isMultiFrame = true; TFilePath dir = m_fp.getParentDir(); QDir qDir(QString::fromStdWString(dir.getWideString())); QString levelName = QRegExp::escape(QString::fromStdWString(m_fp.getWideName())); QString levelType = QString::fromStdString(m_fp.getType()); QString exp(levelName + ".[0-9]{1,4}." + levelType); QRegExp regExp(exp); QStringList list = qDir.entryList(QDir::Files); QStringList livelFrames = list.filter(regExp); int i; for (i = 0; i < livelFrames.size() && isWritable; i++) { TFilePath frame = dir + TFilePath(livelFrames[i].toStdWString()); if (frame.isEmpty() || !frame.isAbsolute()) continue; TFileStatus fs(frame); isWritable = fs.isWritable(); } } if (!isWritable) { string str = "It is not possible to write the output: the file"; str += isMultiFrame ? "s are read only." : " is read only."; MsgBox(WARNING, QString::fromStdString(str)); return; } ToonzScene *scene = 0; TCamera *camera = 0; try { /*-- Xsheetノードに繋がっている各ラインごとに計算するモード。 MultipleRender で Schematic Flows または Fx Schematic Terminal Nodes が選択されている場合 --*/ if (m_multimediaRender && m_fp.getType() != "swf") //swf is not currently supported on multimedia... multimediaRender(); else if (!isPreview && m_fp.getType() == "swf") flashRender(); else /*-- 通常のRendering --*/ rasterRender(isPreview); } catch (TException &e) { MsgBox(WARNING, QString::fromStdString(toString(e.getMessage()))); } catch (...) { MsgBox(WARNING, QObject::tr("It is not possible to complete the rendering.")); } }
MovieGenerator::MovieGenerator(const TFilePath &path, const TDimension &resolution, TOutputProperties &outputProperties, bool useMarkers) { if (path.getType() == "swf" || path.getType() == "scr") m_imp.reset(new FlashMovieGenerator(path, resolution, outputProperties)); else m_imp.reset(new RasterMovieGenerator(path, resolution, outputProperties)); m_imp->m_useMarkers = useMarkers; }
void onDeliver() { if (m_error) { m_error = false; MsgBox(DVGui::CRITICAL, QObject::tr("There was an error saving frames for the %1 level.").arg(QString::fromStdWString(m_fp.withoutParentDir().getWideString()))); } bool isPreview = (m_fp.getType() == "noext"); TImageCache::instance()->remove(toString(m_fp.getWideString() + L".0")); TNotifier::instance()->notify(TSceneNameChange()); if (Preferences::instance()->isGeneratedMovieViewEnabled()) { if (!isPreview && (Preferences::instance()->isDefaultViewerEnabled()) && (m_fp.getType() == "mov" || m_fp.getType() == "avi" || m_fp.getType() == "3gp")) { QString name = QString::fromStdString(m_fp.getName()); int index; if ((index = name.indexOf("#RENDERID")) != -1) //!quite ugly I know.... m_fp = m_fp.withName(name.left(index).toStdWString()); if (!TSystem::showDocument(m_fp)) { QString msg(QObject::tr("It is not possible to display the file %1: no player associated with its format").arg(QString::fromStdWString(m_fp.withoutParentDir().getWideString()))); MsgBox(WARNING, msg); } } else { int r0, r1, step; TApp *app = TApp::instance(); ToonzScene *scene = app->getCurrentScene()->getScene(); TOutputProperties &outputSettings = isPreview ? *scene->getProperties()->getPreviewProperties() : *scene->getProperties()->getOutputProperties(); outputSettings.getRange(r0, r1, step); const TRenderSettings rs = outputSettings.getRenderSettings(); if (r0 == 0 && r1 == -1) r0 = 0, r1 = scene->getFrameCount() - 1; double timeStretchFactor = isPreview ? 1.0 : (double)outputSettings.getRenderSettings().m_timeStretchTo / outputSettings.getRenderSettings().m_timeStretchFrom; r0 = tfloor(r0 * timeStretchFactor); r1 = tceil((r1 + 1) * timeStretchFactor) - 1; TXsheet::SoundProperties *prop = new TXsheet::SoundProperties(); prop->m_frameRate = outputSettings.getFrameRate(); TSoundTrack *snd = app->getCurrentXsheet()->getXsheet()->makeSound(prop); if (outputSettings.getRenderSettings().m_stereoscopic) { assert(!isPreview); ::viewFile(m_fp.withName(m_fp.getName() + "_l"), r0 + 1, r1 + 1, step, isPreview ? rs.m_shrinkX : 1, snd, 0, false, true); ::viewFile(m_fp.withName(m_fp.getName() + "_r"), r0 + 1, r1 + 1, step, isPreview ? rs.m_shrinkX : 1, snd, 0, false, true); } else ::viewFile(m_fp, r0 + 1, r1 + 1, step, isPreview ? rs.m_shrinkX : 1, snd, 0, false, true); } } }
TLevelWriter::TLevelWriter(const TFilePath &path, TPropertyGroup *prop) : TSmartObject(m_classCode), m_path(path), m_properties(prop), m_contentHistory(0) { string ext = path.getType(); if (!prop) m_properties = Tiio::makeWriterProperties(ext); }
bool TFilePath::match(const TFilePath &fp) const { return getParentDir() == fp.getParentDir() && getName() == fp.getName() && getFrame() == fp.getFrame() && getType() == fp.getType(); }
bool TSystem::doesExistFileOrLevel(const TFilePath &fp) { if (TFileStatus(fp).doesExist()) return true; if (fp.isLevelName()) { const TFilePath &parentDir = fp.getParentDir(); if (!TFileStatus(parentDir).doesExist()) return false; TFilePathSet files; try { files = TSystem::readDirectory(parentDir, false, true, true); } catch (...) { } TFilePathSet::iterator it, end = files.end(); for (it = files.begin(); it != end; ++it) { if (it->getLevelNameW() == fp.getLevelNameW()) return true; } } else if (fp.getType() == "psd") { QString name(QString::fromStdWString(fp.getWideName())); name.append(QString::fromStdString(fp.getDottedType())); int sepPos = name.indexOf("#"); int dotPos = name.indexOf(".", sepPos); int removeChars = dotPos - sepPos; int doubleUnderscorePos = name.indexOf("__", sepPos); if (doubleUnderscorePos > 0) removeChars = doubleUnderscorePos - sepPos; name.remove(sepPos, removeChars); TFilePath psdpath(fp.getParentDir() + TFilePath(name.toStdWString())); if (TFileStatus(psdpath).doesExist()) return true; } return false; }
bool isResource(const QString &path) { const TFilePath fp(path.toStdWString()); TFileType::Type type = TFileType::getInfo(fp); return (TFileType::isViewable(type) || type & TFileType::MESH_IMAGE || type == TFileType::AUDIO_LEVEL || type == TFileType::TABSCENE || type == TFileType::TOONZSCENE || fp.getType() == "tpl"); }
std::string ResourceImporter::extractPsdSuffix(TFilePath &path) { if (path.getType() != "psd") return ""; std::string name = path.getName(); int i = name.find("#"); if (i == std::string::npos) return ""; std::string suffix = name.substr(i); path = path.withName(name.substr(0, i)); return suffix; }
TLevelWriterP::TLevelWriterP(const TFilePath &path, TPropertyGroup *winfo) { QString type = QString::fromStdString(toLower(path.getType())); std::map<QString, std::pair<TLevelWriterCreateProc *, bool>>::iterator it; it = LevelWriterTable.find(type); if (it != LevelWriterTable.end()) m_pointer = it->second.first(path, winfo ? winfo->clone() : Tiio::makeWriterProperties(path.getType())); else m_pointer = new TLevelWriter(path, winfo ? winfo->clone() : Tiio::makeWriterProperties(path.getType())); assert(m_pointer); m_pointer->addRef(); }
FlashMovieGenerator(const TFilePath &fp, const TDimension cameraSize, TOutputProperties &properties) : Imp(fp, cameraSize, properties.getFrameRate()) , m_flash(cameraSize.lx, cameraSize.ly, 0, properties.getFrameRate(), properties.getFileFormatProperties("swf")) , m_frameIndex(0) , m_sceneIndex(0) , m_frameCountLoader(0) , m_screenSaverMode(false) { TPointD center(0.5 * cameraSize.lx, 0.5 * cameraSize.ly); m_viewAff = TAffine(); m_screenSaverMode = fp.getType() == "scr"; }
TLevelReaderP::TLevelReaderP(const TFilePath &path, int reader) { QString extension = QString::fromStdString(toLower(path.getType())); LevelReaderKey key(extension, reader); std::map<LevelReaderKey, TLevelReaderCreateProc *>::iterator it; it = LevelReaderTable.find(key); if (it != LevelReaderTable.end()) { m_pointer = it->second(path); assert(m_pointer); } else { m_pointer = new TLevelReader(path); } m_pointer->addRef(); }
TSoundTrackWriterP::TSoundTrackWriterP(const TFilePath &path) { QString type = QString::fromStdString(toLower(path.getType())); std::map<QString, TSoundTrackWriterCreateProc *>::iterator it; it = SoundTrackWriterTable.find(type); if (it != SoundTrackWriterTable.end()) { m_pointer = it->second(path); assert(m_pointer); m_pointer->addRef(); } else { m_pointer = 0; throw TException(path.getWideString() + L"soundtrack writer not implemented"); } }
RasterMovieGenerator(const TFilePath &fp, const TDimension cameraSize, TOutputProperties &properties) : Imp(fp, cameraSize, properties.getFrameRate()) , m_frameIndex(1) , m_started(false) , m_offlineGlContext(*TOfflineGL::getStock(cameraSize)) , m_st(0) , m_whiteSample(0) , m_fileOptions(0) , m_alphaEnabled(false) , m_alphaNeeded(false) , m_status(0) { m_bgColor = TPixel32(255, 255, 255, 0); TPointD center(0.5 * cameraSize.lx, 0.5 * cameraSize.ly); m_viewAff = TTranslation(center); std::string ext = fp.getType(); m_isFrames = ext != "avi" && ext != "mov" && ext != "3gp"; m_fileOptions = properties.getFileFormatProperties(ext); }
void TPaperFormatManager::readPaperFormat(const TFilePath &path) { if (path.getType() != "pap") return; Tifstream is(path); std::string name; TDimensionD size(0, 0); while (is) { char buffer[1024]; is.getline(buffer, sizeof buffer); // i e' il carattere successivo alla fine della linea unsigned int i = 0; for (i = 0; i < sizeof buffer && buffer[i]; i++) { } if (i > 0 && buffer[i - 1] == '\n') i--; while (i > 0 && buffer[i - 1] == ' ') i--; unsigned int j = 0; unsigned int k = 0; // j e' il carattere successivo alla fine del primo token for (j = 0; j < i && buffer[j] != ' '; j++) { } // k e' l'inizio del secondo token (se c'e', altrimenti == i) for (k = j; k < i && buffer[k] == ' '; k++) { } std::string value; if (k < i) value = std::string(buffer + k, i - k); if (buffer[0] == '#') { if (k < i && name == "") name = value; } else if (std::string(buffer).find("WIDTH") == 0) { if (isDouble(value)) size.lx = std::stod(value); } else if (std::string(buffer).find("LENGTH") == 0) { if (isDouble(value)) size.ly = std::stod(value); } } if (name == "" || size.lx == 0 || size.ly == 0) { // TMessage::error("Error reading paper format file : %1",path); } else m_formats[name] = Format(size); }
//!Specialized render invocation for multimedia rendering. Flash rendering //!is currently not supported in this mode. void RenderCommand::multimediaRender() { ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); string ext = m_fp.getType(); #ifdef WIN32 if (ext == "avi") { TPropertyGroup *props = scene->getProperties()->getOutputProperties()->getFileFormatProperties(ext); string codecName = props->getProperty(0)->getValueAsString(); TDimension res = scene->getCurrentCamera()->getRes(); if (!AviCodecRestrictions::canWriteMovie(toWideString(codecName), res)) { QString msg(QObject::tr("The resolution of the output camera does not fit with the options chosen for the output file format.")); MsgBox(WARNING, msg); return; } } #endif; TOutputProperties *prop = scene->getProperties()->getOutputProperties(); //Build thread count int index = prop->getThreadIndex(); const int procCount = TSystem::getProcessorCount(); const int threadCounts[3] = {1, procCount / 2, procCount}; int threadCount = threadCounts[index]; //Build raster granularity size index = prop->getMaxTileSizeIndex(); const int maxTileSizes[4] = { (std::numeric_limits<int>::max)(), TOutputProperties::LargeVal, TOutputProperties::MediumVal, TOutputProperties::SmallVal}; TRenderSettings rs = prop->getRenderSettings(); rs.m_maxTileSize = maxTileSizes[index]; MultimediaRenderer multimediaRenderer(scene, m_fp, prop->getMultimediaRendering(), threadCount); multimediaRenderer.setRenderSettings(rs); #ifdef BRAVODEMO rs.m_mark = loadBravo(scene->getCurrentCamera()->getRes()); #endif TPointD cameraDpi = scene->getCurrentCamera()->getDpi(); multimediaRenderer.setDpi(cameraDpi.x, cameraDpi.y); multimediaRenderer.enablePrecomputing(true); for (int i = 0; i < m_numFrames; ++i, m_r += m_stepd) multimediaRenderer.addFrame(m_r); MultimediaProgressBar *listener = new MultimediaProgressBar(&multimediaRenderer); QObject::connect(listener, SIGNAL(canceled()), &multimediaRenderer, SLOT(onCanceled())); multimediaRenderer.addListener(listener); multimediaRenderer.start(); }
void RenderCommand::rasterRender(bool isPreview) { ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); if (isPreview) { //Let the PreviewFxManager own the rest. Just pass him the current output node. PreviewFxManager::instance()->showNewPreview((TFx *)scene->getXsheet()->getFxDag()->getCurrentOutputFx()); return; } string ext = m_fp.getType(); #ifdef WIN32 if (ext == "avi" && !isPreview) { TPropertyGroup *props = scene->getProperties()->getOutputProperties()->getFileFormatProperties(ext); string codecName = props->getProperty(0)->getValueAsString(); TDimension res = scene->getCurrentCamera()->getRes(); if (!AviCodecRestrictions::canWriteMovie(toWideString(codecName), res)) { QString msg(QObject::tr("The resolution of the output camera does not fit with the options chosen for the output file format.")); MsgBox(WARNING, msg); return; } } #endif; //Extract output properties TOutputProperties *prop = isPreview ? scene->getProperties()->getPreviewProperties() : scene->getProperties()->getOutputProperties(); //Build thread count /*-- Dedicated CPUs のコンボボックス (Single, Half, All) --*/ int index = prop->getThreadIndex(); const int procCount = TSystem::getProcessorCount(); const int threadCounts[3] = {1, procCount / 2, procCount}; int threadCount = threadCounts[index]; /*-- MovieRendererを作る。Previewの場合はファイルパスは空 --*/ MovieRenderer movieRenderer(scene, isPreview ? TFilePath() : m_fp, threadCount, isPreview); TRenderSettings rs = prop->getRenderSettings(); //Build raster granularity size index = prop->getMaxTileSizeIndex(); const int maxTileSizes[4] = { (std::numeric_limits<int>::max)(), TOutputProperties::LargeVal, TOutputProperties::MediumVal, TOutputProperties::SmallVal}; rs.m_maxTileSize = maxTileSizes[index]; //Build #ifdef BRAVODEMO rs.m_mark = loadBravo(scene->getCurrentCamera()->getRes()); #endif /*-- RenderSettingsをセット --*/ movieRenderer.setRenderSettings(rs); /*-- カメラDPIの取得、セット --*/ TPointD cameraDpi = isPreview ? scene->getCurrentPreviewCamera()->getDpi() : scene->getCurrentCamera()->getDpi(); movieRenderer.setDpi(cameraDpi.x, cameraDpi.y); movieRenderer.enablePrecomputing(true); /*-- プログレス ダイアログの作成 --*/ RenderListener *listener = new RenderListener(movieRenderer.getTRenderer(), m_fp, ((m_numFrames - 1) / m_step) + 1, isPreview); QObject::connect(listener, SIGNAL(canceled()), &movieRenderer, SLOT(onCanceled())); movieRenderer.addListener(listener); bool fieldRendering = rs.m_fieldPrevalence != TRenderSettings::NoField; /*-- buildSceneFxの進行状況を表示するプログレスバー --*/ QProgressBar *buildSceneProgressBar = new QProgressBar(TApp::instance()->getMainWindow()); buildSceneProgressBar->setAttribute(Qt::WA_DeleteOnClose); buildSceneProgressBar->setWindowFlags(Qt::SubWindow | Qt::Dialog | Qt::WindowStaysOnTopHint); buildSceneProgressBar->setMinimum(0); buildSceneProgressBar->setMaximum(m_numFrames - 1); buildSceneProgressBar->setValue(0); buildSceneProgressBar->move(600, 500); buildSceneProgressBar->setWindowTitle("Building Schematic..."); buildSceneProgressBar->show(); for (int i = 0; i < m_numFrames; ++i, m_r += m_stepd) { buildSceneProgressBar->setValue(i); if (rs.m_stereoscopic) scene->shiftCameraX(-rs.m_stereoscopicShift / 2); TFxPair fx; fx.m_frameA = buildSceneFx(scene, m_r, rs.m_shrinkX, isPreview); if (fieldRendering && !isPreview) fx.m_frameB = buildSceneFx(scene, m_r + 0.5 / m_timeStretchFactor, rs.m_shrinkX, isPreview); else if (rs.m_stereoscopic) { scene->shiftCameraX(rs.m_stereoscopicShift); fx.m_frameB = buildSceneFx(scene, m_r + 0.5 / m_timeStretchFactor, rs.m_shrinkX, isPreview); scene->shiftCameraX(-rs.m_stereoscopicShift / 2); } else fx.m_frameB = TRasterFxP(); /*-- movieRendererにフレーム毎のFxを登録 --*/ movieRenderer.addFrame(m_r, fx); } /*-- プログレスバーを閉じる --*/ buildSceneProgressBar->close(); //resetViewer(); //TODO cancella le immagini dell'eventuale render precedente //FileViewerPopupPool::instance()->getCurrent()->onClose(); movieRenderer.start(); }
bool RenderCommand::init(bool isPreview) { ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); TSceneProperties *sprop = scene->getProperties(); /*-- Preview/Renderに応じてそれぞれのSettingを取得 --*/ TOutputProperties &outputSettings = isPreview ? *sprop->getPreviewProperties() : *sprop->getOutputProperties(); outputSettings.getRange(m_r0, m_r1, m_step); /*-- シーン全体のレンダリングの場合、m_r1をScene長に設定 --*/ if (m_r0 == 0 && m_r1 == -1) { m_r0 = 0; m_r1 = scene->getFrameCount() - 1; } if (m_r0 < 0) m_r0 = 0; if (m_r1 >= scene->getFrameCount()) m_r1 = scene->getFrameCount() - 1; if (m_r1 < m_r0) { MsgBox(WARNING, QObject::tr("The command cannot be executed because the scene is empty.")); return false; // throw TException("empty scene"); // non so perche', ma termina il programma // nonostante il try all'inizio } // Initialize the preview case /*TRenderSettings rs = sprop->getPreviewProperties()->getRenderSettings(); TRenderSettings rso = sprop->getOutputProperties()->getRenderSettings(); rs.m_stereoscopic=true; rs.m_stereoscopicShift=0.05; rso.m_stereoscopic=true; rso.m_stereoscopicShift=0.05; sprop->getPreviewProperties()->setRenderSettings(rs); sprop->getOutputProperties()->setRenderSettings(rso);*/ if (isPreview) { /*-- PreviewではTimeStretchを考慮しないので、そのままフレーム値を格納してゆく --*/ m_numFrames = (int)(m_r1 - m_r0 + 1); m_r = m_r0; m_stepd = m_step; m_multimediaRender = 0; return true; } // Full render case // Read the output filepath TFilePath fp = outputSettings.getPath(); /*-- ファイル名が指定されていない場合は、シーン名を出力ファイル名にする --*/ if (fp.getWideName() == L"") fp = fp.withName(scene->getScenePath().getName()); /*-- ラスタ画像の場合、ファイル名にフレーム番号を追加 --*/ if (TFileType::getInfo(fp) == TFileType::RASTER_IMAGE || fp.getType() == "pct" || fp.getType() == "pic" || fp.getType() == "pict") //pct e' un formato"livello" (ha i settings di quicktime) ma fatto di diversi frames fp = fp.withFrame(TFrameId::EMPTY_FRAME); fp = scene->decodeFilePath(fp); if (!TFileStatus(fp.getParentDir()).doesExist()) { try { TFilePath parent = fp.getParentDir(); TSystem::mkDir(parent); DvDirModel::instance()->refreshFolder(parent.getParentDir()); } catch (TException &e) { MsgBox(WARNING, QObject::tr("It is not possible to create folder : %1").arg(QString::fromStdString(toString(e.getMessage())))); return false; } catch (...) { MsgBox(WARNING, QObject::tr("It is not possible to create a folder.")); return false; } } m_fp = fp; // Retrieve camera infos const TCamera *camera = isPreview ? scene->getCurrentPreviewCamera() : scene->getCurrentCamera(); TDimension cameraSize = camera->getRes(); TPointD cameraDpi = camera->getDpi(); // Retrieve render interval/step/times double stretchTo = (double)outputSettings.getRenderSettings().m_timeStretchTo; double stretchFrom = (double)outputSettings.getRenderSettings().m_timeStretchFrom; m_timeStretchFactor = stretchTo / stretchFrom; m_stepd = m_step / m_timeStretchFactor; int stretchedR0 = tfloor(m_r0 * m_timeStretchFactor); int stretchedR1 = tceil((m_r1 + 1) * m_timeStretchFactor) - 1; m_r = stretchedR0 / m_timeStretchFactor; m_numFrames = (stretchedR1 - stretchedR0) / m_step + 1; // Update the multimedia render switch m_multimediaRender = outputSettings.getMultimediaRendering(); return true; }
void MovieRenderer::Imp::prepareForStart() { struct locals { static void eraseUncompatibleExistingLevel(const TFilePath &fp, const TDimension &imageSize) // nothrow { assert(!fp.isEmpty()); if (TSystem::doesExistFileOrLevel(fp)) { bool remove = false; // In case the raster specifics are different from those of a currently // existing movie, erase it try { TLevelReaderP lr(fp); lr->loadInfo(); const TImageInfo *info = lr->getImageInfo(); if (!info || info->m_lx != imageSize.lx || info->m_ly != imageSize.ly) TSystem::removeFileOrLevel(fp); // nothrow } catch (...) { // Same if the level could not be read/opened TSystem::removeFileOrLevel(fp); // nothrow } // NOTE: The level removal procedure could still fail. // In this case, no signaling takes place. The level readers will throw // when the time to write on the file comes, leading to a render failure. } } }; TOutputProperties *oprop = m_scene->getProperties()->getOutputProperties(); double frameRate = (double)oprop->getFrameRate(); /*-- Frame rate の stretch --*/ double stretchFactor = oprop->getRenderSettings().m_timeStretchTo / oprop->getRenderSettings().m_timeStretchFrom; frameRate *= stretchFactor; // Get the shrink int shrinkX = m_renderSettings.m_shrinkX, shrinkY = m_renderSettings.m_shrinkY; //Build the render area TPointD cameraPos(-0.5 * m_frameSize.lx, -0.5 * m_frameSize.ly); TDimensionD cameraRes(double(m_frameSize.lx) / shrinkX, double(m_frameSize.ly) / shrinkY); TDimension cameraResI(cameraRes.lx, cameraRes.ly); TRectD renderArea(cameraPos.x, cameraPos.y, cameraPos.x + cameraRes.lx, cameraPos.y + cameraRes.ly); setRenderArea(renderArea); if (!m_fp.isEmpty()) { try // Construction of a LevelUpdater may throw (well, almost ANY operation on a LevelUpdater { // could throw). But due to backward compatibility this function is assumed to be non-throwing. if (!m_renderSettings.m_stereoscopic) { locals::eraseUncompatibleExistingLevel(m_fp, cameraResI); m_levelUpdaterA.reset(new LevelUpdater(m_fp, oprop->getFileFormatProperties(m_fp.getType()))); m_levelUpdaterA->getLevelWriter()->setFrameRate(frameRate); } else { TFilePath leftFp = m_fp.withName(m_fp.getName() + "_l"); TFilePath rightFp = m_fp.withName(m_fp.getName() + "_r"); locals::eraseUncompatibleExistingLevel(leftFp, cameraResI); locals::eraseUncompatibleExistingLevel(rightFp, cameraResI); m_levelUpdaterA.reset(new LevelUpdater(leftFp, oprop->getFileFormatProperties(leftFp.getType()))); m_levelUpdaterA->getLevelWriter()->setFrameRate(frameRate); m_levelUpdaterB.reset(new LevelUpdater(rightFp, oprop->getFileFormatProperties(rightFp.getType()))); m_levelUpdaterB->getLevelWriter()->setFrameRate(frameRate); } } catch (...) { // If we get here, it's because one of the LevelUpdaters could not be created. So, let's say // that if one could not be created, then ALL OF THEM couldn't (ie saving is not possible at all). m_levelUpdaterA.reset(); m_levelUpdaterB.reset(); } } }
bool IoCmd::exportLevel(const TFilePath &path, TXshSimpleLevel *sl, ExportLevelOptions opts, OverwriteCallbacks *overwriteCB, ProgressCallbacks *progressCB) { struct Locals { const TFilePath &m_path; TXshSimpleLevel *m_sl; const ExportLevelOptions &m_opts; OverwriteCallbacks *m_overwriteCB; ProgressCallbacks *m_progressCB; bool exportToMultifile() { ImageExporter exporter(*m_sl, m_opts); TXshLevelType outputLevelType = (m_path.getType() == "tlv") ? TZP_TYPE : OVL_TYPE; bool firstTime = true; for (int i = 0; i < m_sl->getFrameCount(); ++i) { if (m_progressCB->canceled()) return false; // Prepare frame export path TFilePath fpout; if (m_opts.m_forRetas) { QString pathOut = QString::fromStdWString(m_path.getParentDir().getWideString()) + "\\" + QString::fromStdString(m_path.getName()) + QString::fromStdString(m_sl->index2fid(i).expand()) + "." + QString::fromStdString(m_path.getType()); fpout = TFilePath(pathOut.toStdString()); } else fpout = TFilePath(m_path.withFrame(m_sl->index2fid(i))); // Ask for overwrite permission in case a level with the built path already exists if (firstTime) { firstTime = false; if (TSystem::doesExistFileOrLevel(fpout)) { QApplication::restoreOverrideCursor(); bool overwrite = m_overwriteCB->overwriteRequest(fpout); QApplication::setOverrideCursor(Qt::WaitCursor); if (!overwrite) return false; } } // Retrieve the image to export at current frame TImageP img = exporter.exportedImage(m_sl->index2fid(i), outputLevelType); assert(img); // Save the prepared fullcolor image to file TImageWriter iw(fpout); iw.setProperties(m_opts.m_props); iw.save(img); m_progressCB->setValue(i + 1); } return true; } bool exportToTlv() { TFilePath fp(m_path.withNoFrame()); // Remove any existing level if (TSystem::doesExistFileOrLevel(fp)) { bool overwrite = m_overwriteCB->overwriteRequest(fp); if (!overwrite) return false; TSystem::deleteFile(fp); } TSystem::removeFileOrLevel(fp.withType("tpl")); // Export level TLevelWriterP lw(fp); ImageExporter exporter(*m_sl, m_opts); for (int i = 0; i < m_sl->getFrameCount(); ++i) { if (m_progressCB->canceled()) return false; const TFrameId &fid = m_sl->index2fid(i); TImageP img = exporter.exportedImage(fid, TZP_TYPE); assert(img); lw->getFrameWriter(fid)->save(img); m_progressCB->setValue(i + 1); } return true; } }; // Locals // Use default values in case some were not specified by input // Level if (!sl) { sl = TApp::instance()->getCurrentLevel()->getSimpleLevel(); if (!sl) { DVGui::error(QObject::tr("No level selected!")); return false; } } if (sl->isEmpty()) return false; // Output properties if (!opts.m_props) { ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); opts.m_props = scene->getProperties()->getOutputProperties()->getFileFormatProperties(path.getType()); } // Camera (todo) assert(opts.m_camera.getRes().lx > 0 && opts.m_camera.getRes().ly > 0); // Callbacks std::auto_ptr<OverwriteCallbacks> overwriteDefault( overwriteCB ? 0 : (overwriteCB = new ExportOverwriteCB())); std::auto_ptr<ProgressCallbacks> progressDefault( progressCB ? 0 : (progressCB = new ExportProgressCB())); // Initialize variables Locals locals = {path, sl, opts, overwriteCB, progressCB}; progressCB->setProcessedName(QString::fromStdWString(path.getWideString())); progressCB->setRange(0, sl->getFrameCount()); // Export level BusyCursorOverride cursorOverride; QCoreApplication::processEvents(); // Refresh screen. ...But WHY is this // necessary? try { return (path.getType() == "tlv") ? assert(sl->getType() == PLI_XSHLEVEL), locals.exportToTlv() : locals.exportToMultifile(); } catch (...) { return false; } }
void SceneLevel::save() { TFilePath fp = m_oldPath; SceneResource::updatePath(fp); TFilePath actualFp = m_scene->decodeFilePath(fp); actualFp = restorePsdPath(actualFp); TFilePath oldActualPath = restorePsdPath(m_oldActualPath); assert(actualFp.getWideString() == L"" || actualFp.getWideString()[0] != L'+'); if (actualFp != oldActualPath || !TSystem::doesExistFileOrLevel(oldActualPath) || m_sl->getProperties()->getDirtyFlag() || (m_sl->getPalette() && m_sl->getPalette()->getDirtyFlag())) { try { TSystem::touchParentDir(actualFp); if (actualFp != oldActualPath && TSystem::doesExistFileOrLevel(oldActualPath) && m_sl->getProperties()->getDirtyFlag() == false && (!m_sl->getPalette() || (m_sl->getPalette() && m_sl->getPalette()->getDirtyFlag() == false))) { try { TXshSimpleLevel::copyFiles(actualFp, oldActualPath); } catch (...) { } //Must NOT KEEP FRAMES, it generate a level frames bind necessary to imageBuilder path refresh. m_sl->setPath(fp, false); } else { m_sl->save(actualFp, oldActualPath); if ((actualFp.getType() == "tlv" || actualFp.getType() == "pli") && actualFp != oldActualPath && m_oldRefImgPath != TFilePath()) { //Devo preoccuparmi dell'eventuale livello colormodel TFilePath actualRefImagPath = m_scene->decodeFilePath(m_oldRefImgPath); TFilePath actualRefImagPathTpl = actualRefImagPath.withType("tpl"); TFilePath oldRefImagPathTpl = m_oldActualRefImgPath.withType("tpl"); TSystem::copyFile(actualRefImagPath, m_oldActualRefImgPath); if (actualRefImagPath.getType() == "tlv") TSystem::copyFile(actualRefImagPathTpl, oldRefImagPathTpl); } if (actualFp.getType() == "tif" || actualFp.getType() == "tiff" || actualFp.getType() == "tga" || actualFp.getType() == "tzi") { TFilePath clnin = oldActualPath.withNoFrame().withType("cln"); if (TSystem::doesExistFileOrLevel(clnin)) TSystem::copyFile(actualFp.withNoFrame().withType("cln"), clnin); } } //Se il livello e' tlv verifico se esiste il corrispondente unpainted ed in caso affermativo lo copio. //Questo controllo viene fatto qui e non nella copia o nel salvataggio del livello perche' in generale //non si vuole che il livello unpainted venga copiato con il livello. if (actualFp.getType() == "tlv") { TFilePath oldUnpaintedLevelPath = oldActualPath.getParentDir() + TFilePath(oldActualPath.getName() + "-unpainted." + oldActualPath.getType()); TFilePath unpaintedLevelPath = actualFp.getParentDir() + TFilePath(actualFp.getName() + "-unpainted." + actualFp.getType()); if (TSystem::doesExistFileOrLevel(oldUnpaintedLevelPath) && !TSystem::doesExistFileOrLevel(unpaintedLevelPath)) TSystem::copyFile(unpaintedLevelPath, oldUnpaintedLevelPath); TFilePath oldUnpaintedPalettePath = oldUnpaintedLevelPath.withType("tpl"); TFilePath unpaintedPalettePath = unpaintedLevelPath.withType("tpl"); if (TSystem::doesExistFileOrLevel(oldUnpaintedPalettePath) && !TSystem::doesExistFileOrLevel(unpaintedPalettePath)) TSystem::copyFile(unpaintedPalettePath, oldUnpaintedPalettePath); } } catch (...) { } } fp = m_oldScannedPath; if (fp != TFilePath()) { SceneResource::updatePath(fp); actualFp = m_scene->decodeFilePath(fp); if (actualFp != m_oldActualScannedPath && TSystem::doesExistFileOrLevel(m_oldActualScannedPath)) { try { TSystem::touchParentDir(actualFp); TSystem::copyFileOrLevel_throw(actualFp, m_oldActualScannedPath); m_sl->clearFrames(); m_sl->load(); } catch (...) { } } } }