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;
		}
void FilmstripFrameHeadGadget::setCurrentFrame(int index) const
{
	TXshSimpleLevel *level = m_filmstrip->getLevel();
	if (!level)
		return;
	TFrameId fid = level->index2fid(index);
	if (fid >= TFrameId(1))
		TApp::instance()->getCurrentFrame()->setFid(fid);
}
		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;
		}
示例#4
0
void FilmstripFrames::select(int index, SelectionMode mode) {
  TXshSimpleLevel *sl = getLevel();

  bool outOfRange = !sl || index < 0 || index >= sl->getFrameCount();

  TFrameId fid;
  if (!outOfRange) fid = index2fid(index);

  switch (mode) {
  // select one frame only
  case ONLY_SELECT:
    m_selection->selectNone();
    if (!outOfRange) m_selection->select(fid);
    break;
  case SIMPLE_SELECT:
    // Bail out if fid is already selected
    if (!outOfRange && m_selection->isSelected(fid)) return;

    m_selection->selectNone();
    if (!outOfRange) m_selection->select(fid);
    break;

  case SHIFT_SELECT:
    if (outOfRange) return;

    // Bail out if fid is already selected
    if (m_selection->isSelected(fid)) return;

    if (m_selection->isEmpty())
      m_selection->select(fid);
    else {
      TXshSimpleLevel *sl = getLevel();
      if (!sl) return;

      // seleziono il range da fid al piu' vicino frame selezionato (in entrambe
      // le direzioni)
      int frameCount = sl->getFrameCount();

      // calcolo il limite inferiore della selezione
      int ia = index;
      while (ia > 0 && !m_selection->isSelected(sl->index2fid(ia - 1))) ia--;
      if (ia == 0) ia = index;

      // calcolo il limite superiore della selezione
      int ib = index;
      while (ib < frameCount - 1 &&
             !m_selection->isSelected(sl->index2fid(ib + 1)))
        ib++;
      if (ib == frameCount - 1) ib = index;

      // seleziono
      for (int i = ia; i <= ib; i++) m_selection->select(sl->index2fid(i));
    }
    break;

  case CTRL_SELECT:
    if (outOfRange) return;

    m_selection->select(fid, !m_selection->isSelected(fid));
    break;

  case START_DRAG_SELECT:
    m_selection->selectNone();

    if (outOfRange) {
      m_dragSelectionStartIndex = m_dragSelectionEndIndex = -1;

      break;
    }

    m_selection->select(fid);
    m_dragSelectionStartIndex = index;
    break;

  case DRAG_SELECT:
    if (outOfRange || m_dragSelectionStartIndex < 0 ||
        m_dragSelectionEndIndex == index)
      return;

    m_dragSelectionEndIndex = index;

    m_selection->selectNone();

    int ia = m_dragSelectionStartIndex;
    int ib = index;

    if (ia > ib) std::swap(ia, ib);

    for (int i = ia; i <= ib; ++i) m_selection->select(index2fid(i));

    break;
  }

  TObjectHandle *objectHandle = TApp::instance()->getCurrentObject();
  if (objectHandle->isSpline()) objectHandle->setIsSpline(false);

  // Update current selection
  m_selection->makeCurrent();

  TSelectionHandle *selHandle = TApp::instance()->getCurrentSelection();
  selHandle->notifySelectionChanged();
}
示例#5
0
TFrameId FilmstripFrames::index2fid(int index) const {
  TXshSimpleLevel *sl = getLevel();
  if (!sl || index < 0) return TFrameId();
  return sl->index2fid(index);
}
Q_INVOKABLE QScriptValue Rasterizer::rasterize(QScriptValue arg) {
  Image *img        = qscriptvalue_cast<Image *>(arg);
  Level *level      = qscriptvalue_cast<Level *>(arg);
  TPalette *palette = 0;
  if (img) {
    if (img->getType() != "Vector")
      return context()->throwError(
          tr("Expected a vector image: %1").arg(arg.toString()));
    palette = !!img->getImg() ? img->getImg()->getPalette() : 0;
  } else if (level) {
    if (level->getType() != "Vector")
      return context()->throwError(
          tr("Expected a vector level: %1").arg(arg.toString()));
    palette =
        level->getSimpleLevel() ? level->getSimpleLevel()->getPalette() : 0;
  } else {
    return context()->throwError(
        tr("Argument must be a vector level or image : ").arg(arg.toString()));
  }
  if (!palette) {
    return context()->throwError(tr("%1 has no palette").arg(arg.toString()));
  }

  TDimension res(m_xres, m_yres);
  TCamera camera;
  camera.setRes(res);
  camera.setSize(TDimensionD(m_xres / m_dpi, m_yres / m_dpi));
  TPointD dpi = camera.getDpi();
  TAffine aff = camera.getStageToCameraRef();

  QScriptValue result;
  int n               = 0;
  TXshSimpleLevel *sl = 0;
  if (level) {
    result = create(engine(), new Level());
    n      = level->getFrameCount();
    sl     = level->getSimpleLevel();
  }

  if (m_colorMapped) {
    // vector -> toonz image
    if (img) {
      TImageP outImg = vectorToToonzRaster(img->getImg(), res, aff, dpi);
      result         = create(engine(), new Image(outImg));
    } else {
      for (int i = 0; i < n; i++) {
        TFrameId fid    = sl->index2fid(i);
        TImageP drawing = sl->getFrame(fid, false);
        TImageP outImg  = vectorToToonzRaster(drawing, res, aff, dpi);
        setFrame(engine(), result, fid, outImg);
      }
    }
  } else {
    // vector -> full color
    TPixel32 bgColor = TPixel32::White;

    TOfflineGL *glContext = new TOfflineGL(res);
    glContext->makeCurrent();

    TVectorRenderData rd(TVectorRenderData::ProductionSettings(), aff, TRect(),
                         palette);
    rd.m_antiAliasing = m_antialiasing;

    if (img) {
      TImageP outImg =
          renderVectorImage(glContext, rd, dpi, img->getImg(), bgColor);
      result = create(engine(), new Image(outImg));
    } else {
      for (int i = 0; i < n; i++) {
        TFrameId fid    = sl->index2fid(i);
        TImageP drawing = sl->getFrame(fid, false);
        glContext->clear(TPixel32::White);
        TImageP outImg =
            renderVectorImage(glContext, rd, dpi, drawing, bgColor);
        setFrame(engine(), result, fid, outImg);
      }
    }
    delete glContext;
  }

  return result;
}
示例#7
0
TImage *TTool::touchImage() {
  if (!m_application) return 0;

  m_cellsData.clear();

  m_isLevelCreated  = false;
  m_isFrameCreated  = false;
  Preferences *pref = Preferences::instance();

  bool isAutoCreateEnabled   = pref->isAutoCreateEnabled();
  bool animationSheetEnabled = pref->isAnimationSheetEnabled();
  bool isAutoStretchEnabled  = pref->isAutoStretchEnabled();

  TFrameHandle *currentFrame    = m_application->getCurrentFrame();
  TXshLevelHandle *currentLevel = m_application->getCurrentLevel();

  if (currentFrame->isEditingLevel()) {
    // Editing level

    // no level => return 0
    TXshLevel *xl = currentLevel->getLevel();
    if (!xl) return 0;
    TXshSimpleLevel *sl = xl->getSimpleLevel();
    if (!sl || sl->isEmpty()) return 0;

    TFrameId fid = currentFrame->getFid();
    TImageP img  = sl->getFrame(fid, true);
    if (!img) {
      // no drawing found
      if (sl->isSubsequence() || sl->isReadOnly() || !isAutoCreateEnabled)
        return 0;

      // create a new drawing
      img = sl->createEmptyFrame();
      sl->setFrame(fid, img);
      currentLevel->notifyLevelChange();
      m_isFrameCreated = true;
    }
    return img.getPointer();
  } else {
    // editing xsheet
    if (m_application->getCurrentObject()->isSpline()) return 0;

    TSceneHandle *currentScene = m_application->getCurrentScene();
    ToonzScene *scene          = currentScene->getScene();
    int row                    = currentFrame->getFrame();
    int col = m_application->getCurrentColumn()->getColumnIndex();
    if (col < 0) return 0;

    TXsheetHandle *currentXsheet = m_application->getCurrentXsheet();
    TXsheet *xsh                 = currentXsheet->getXsheet();
    if (!xsh) return 0;

    TXshCell cell       = xsh->getCell(row, col);
    TXshSimpleLevel *sl = cell.getSimpleLevel();

    if (sl != 0) {
      // current cell is not empty
      if (isAutoCreateEnabled && animationSheetEnabled && row > 0 &&
          xsh->getCell(row - 1, col) == xsh->getCell(row, col)) {
        // animationSheet is enabled and the current cell is a "hold". We must
        // create a new drawing.
        // measure the hold length (starting from the current row) : r0-r1
        int r0 = row, r1 = row;
        if (isAutoStretchEnabled)
          while (xsh->getCell(r1 + 1, col) == cell) r1++;
        // find the proper frameid (possibly addisng suffix, in order to avoid a
        // fid already used)
        TFrameId fid = getNewFrameId(sl, row);
        // create the new drawing
        TImageP img      = sl->createEmptyFrame();
        m_isFrameCreated = true;
        // insert the drawing in the level
        sl->setFrame(fid, img);
        // update the cell
        cell = TXshCell(sl, fid);
        // update the xsheet (change the current cell and possibly all the
        // following "hold")
        for (int r = r0; r <= r1; r++) xsh->setCell(r, col, cell);
        // notify
        currentXsheet->notifyXsheetChanged();
        currentScene->notifyCastChange();
        currentLevel->notifyLevelChange();
        m_cellsData.push_back(r0);
        m_cellsData.push_back(r1);
        m_cellsData.push_back(0);
      }
      // we've found the image. return it.
      return cell.getImage(true).getPointer();
    }

    // current cell is empty.
    if (!isAutoCreateEnabled) return 0;

    // get the column range
    int r0, r1;
    xsh->getCellRange(col, r0, r1);

    if (animationSheetEnabled && r0 <= r1) {
      // animation sheet enabled and not empty column. We must create a new
      // drawing in the column level and possibly add "holds"

      // find the last not-empty cell before the current one (a) and the first
      // after (b)
      int a = row - 1, b = row + 1;
      while (a >= r0 && xsh->getCell(a, col).isEmpty()) a--;
      while (b <= r1 && xsh->getCell(b, col).isEmpty()) b++;

      // find the level we must attach to
      if (a >= r0) {
        // there is a not-emtpy cell before the current one
        sl = xsh->getCell(a, col).getSimpleLevel();
      } else if (b <= r1) {
        sl = xsh->getCell(b, col).getSimpleLevel();
      }
      if (sl) {
        // note: sl should be always !=0 (the column is not empty)
        // if - for some reason - it is ==0 then we skip to the standard (i.e.
        // !animationSheetEnabled) beahviour

        // create the drawing
        // find the proper frameid (possibly addisng suffix, in order to avoid a
        // fid already used)
        TFrameId fid = getNewFrameId(sl, row);
        // create the new drawing
        TImageP img      = sl->createEmptyFrame();
        m_isFrameCreated = true;
        // insert the drawing in the level
        sl->setFrame(fid, img);
        // update the cell
        cell = TXshCell(sl, fid);
        xsh->setCell(row, col, cell);

        // create holds
        if (!isAutoStretchEnabled) {
          m_cellsData.push_back(row);
          m_cellsData.push_back(row);
          m_cellsData.push_back(2);  // vuoto => nuovo
        } else {
          if (a >= r0) {
            // create a hold before : [a+1, row-1]
            TXshCell aCell = xsh->getCell(a, col);
            for (int i = a + 1; i < row; i++) xsh->setCell(i, col, aCell);
            m_cellsData.push_back(a + 1);
            m_cellsData.push_back(row - 1);
            m_cellsData.push_back(1);  // vuoto => vecchio

            if (b <= r1 && xsh->getCell(b, col).getSimpleLevel() == sl) {
              // create also a hold after
              for (int i = row + 1; i < b; i++) xsh->setCell(i, col, cell);
              m_cellsData.push_back(row);
              m_cellsData.push_back(b - 1);
              m_cellsData.push_back(2);  // vuoto => nuovo
            } else {
              m_cellsData.push_back(row);
              m_cellsData.push_back(row);
              m_cellsData.push_back(2);  // vuoto => nuovo
            }
          } else if (b <= r1) {
            // create a hold after
            for (int i = row + 1; i < b; i++) xsh->setCell(i, col, cell);
            m_cellsData.push_back(row);
            m_cellsData.push_back(b - 1);
            m_cellsData.push_back(2);  // vuoto => nuovo
          }
        }
      }
      // notify & return
      currentXsheet->notifyXsheetChanged();
      currentScene->notifyCastChange();
      currentLevel->notifyLevelChange();
      return cell.getImage(true).getPointer();
    }

    if (row > 0 && xsh->getCell(row - 1, col).getSimpleLevel() != 0 &&
        !animationSheetEnabled) {
      sl = xsh->getCell(row - 1, col).getSimpleLevel();
      if (sl->getType() != OVL_XSHLEVEL ||
          sl->getPath().getFrame() != TFrameId::NO_FRAME) {
        // la cella precedente contiene un drawing di un livello. animationSheet
        // e' disabilitato
        // creo un nuovo frame
        currentLevel->setLevel(sl);
        if (sl->isSubsequence() || sl->isReadOnly()) return 0;
        TFrameId fid     = sl->index2fid(sl->getFrameCount());
        TImageP img      = sl->createEmptyFrame();
        m_isFrameCreated = true;
        sl->setFrame(fid, img);
        cell = TXshCell(sl, fid);
        xsh->setCell(row, col, cell);
        currentXsheet->notifyXsheetChanged();
        currentScene->notifyCastChange();
        currentLevel->notifyLevelChange();
        return img.getPointer();
      }
    }

    // animation sheet disabled or empty column. autoCreate is enabled: we must
    // create a new level
    int levelType    = pref->getDefLevelType();
    TXshLevel *xl    = scene->createNewLevel(levelType);
    sl               = xl->getSimpleLevel();
    m_isLevelCreated = true;

    // create the drawing
    TFrameId fid = animationSheetEnabled ? getNewFrameId(sl, row) : TFrameId(1);
    TImageP img  = sl->createEmptyFrame();
    m_isFrameCreated = true;
    sl->setFrame(fid, img);
    cell = TXshCell(sl, fid);
    xsh->setCell(row, col, cell);
    if (animationSheetEnabled) {
      m_cellsData.push_back(row);
      m_cellsData.push_back(row);
      m_cellsData.push_back(2);  // vuoto => nuovo
    }

    currentXsheet->notifyXsheetChanged();
    currentScene->notifyCastChange();
    currentLevel->notifyLevelChange();
    return img.getPointer();
  }
}