Example #1
0
static bool canMergeColumns(int column, int mColumn, bool forMatchlines) {
  TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();

  if (xsh->getColumn(column)->isLocked()) return false;

  int start, end;
  xsh->getCellRange(column, start, end);

  if (start > end) return false;
  std::vector<TXshCell> cell(end - start + 1);
  std::vector<TXshCell> mCell(end - start + 1);

  xsh->getCells(start, column, cell.size(), &(cell[0]));
  xsh->getCells(start, mColumn, cell.size(), &(mCell[0]));

  TXshSimpleLevel *level = 0, *mLevel = 0;
  TXshLevelP xl;

  for (int i = 0; i < (int)cell.size(); i++) {
    if (cell[i].isEmpty() || mCell[i].isEmpty()) continue;
    if (!level) {
      level = cell[i].getSimpleLevel();
      xl    = cell[i].m_level;
    }

    else if (level != cell[i].getSimpleLevel())
      return false;

    if (!mLevel)
      mLevel = mCell[i].getSimpleLevel();
    else if (mLevel != mCell[i].getSimpleLevel())
      return false;

    if (!mLevel || !level ||  // potrebbero non essere dei simplelevel
        (forMatchlines && (level->getType() != TZP_XSHLEVEL ||
                           mLevel->getType() != TZP_XSHLEVEL)))
      return false;
    else if (!forMatchlines) {
      if (level->getType() != mLevel->getType()) return false;
      if (level->getType() != PLI_XSHLEVEL && level->getType() != OVL_XSHLEVEL)
        return false;
      // Check level type write support. Based on TTool::updateEnabled()
      if (level->getType() == OVL_XSHLEVEL &&
          (level->getPath().getType() == "psd" ||     // PSD files.
           level->is16BitChannelLevel() ||            // 16bpc images.
           level->getProperties()->getBpp() == 1)) {  // Black & White images.
        return false;
      }
    }
  }
  return true;
}
Example #2
0
void CellsMover::getCells(std::vector<TXshCell> &cells, int r, int c) const {
  for (int i = 0; i < (int)cells.size(); i++) cells[i] = TXshCell();
  TXsheet *xsh                                         = getXsheet();
  for (int i = 0; i < m_colCount; i++) {
    TXshColumn *column = xsh->getColumn(c + i);
    if (column && column->isLocked()) continue;
    xsh->getCells(r, c + i, m_rowCount, &cells[m_rowCount * i]);
  }
}
Example #3
0
bool canMergeColumns(int column, int mColumn, bool forMatchlines) {
  TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
  int start, end;
  xsh->getCellRange(column, start, end);

  if (start > end) return false;
  std::vector<TXshCell> cell(end - start + 1);
  std::vector<TXshCell> mCell(end - start + 1);

  xsh->getCells(start, column, cell.size(), &(cell[0]));
  xsh->getCells(start, mColumn, cell.size(), &(mCell[0]));

  TXshSimpleLevel *level = 0, *mLevel = 0;
  TXshLevelP xl;

  for (int i = 0; i < (int)cell.size(); i++) {
    if (cell[i].isEmpty() || mCell[i].isEmpty()) continue;
    if (!level) {
      level = cell[i].getSimpleLevel();
      xl    = cell[i].m_level;
    }

    else if (level != cell[i].getSimpleLevel())
      return false;

    if (!mLevel)
      mLevel = mCell[i].getSimpleLevel();
    else if (mLevel != mCell[i].getSimpleLevel())
      return false;

    if (!mLevel || !level ||  // potrebbero non essere dei simplelevel
        (forMatchlines && (level->getType() != TZP_XSHLEVEL ||
                           mLevel->getType() != TZP_XSHLEVEL)))
      return false;
    else if (!forMatchlines) {
      if (level->getType() != mLevel->getType()) return false;
      if (level->getType() != PLI_XSHLEVEL && level->getType() != OVL_XSHLEVEL)
        return false;
    }
  }
  return true;
}
Example #4
0
void mergeColumns(int column, int mColumn, bool isRedo)
{
	MergeColumnsSessionId++;
	TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
	int start, end;
	xsh->getCellRange(column, start, end);

	if (start > end)
		return;
	vector<TXshCell> cell(end - start + 1);
	vector<TXshCell> mCell(end - start + 1);

	xsh->getCells(start, column, cell.size(), &(cell[0]));

	xsh->getCells(start, mColumn, cell.size(), &(mCell[0]));

	TXshColumn *col = xsh->getColumn(column);
	TXshColumn *mcol = xsh->getColumn(mColumn);

	vector<MatchlinePair> matchingLevels;

	std::set<TFrameId> alreadyDoneSet;

	TXshSimpleLevel *level = 0, *mLevel = 0;
	TXshLevelP xl;
	bool areRasters = false;

	std::map<TFrameId, QString> images;

	for (int i = 0; i < (int)cell.size(); i++) {
		if (cell[i].isEmpty() || mCell[i].isEmpty())
			continue;
		if (!level) {
			level = cell[i].getSimpleLevel();
			xl = cell[i].m_level;
		}

		else if (level != cell[i].getSimpleLevel()) {
			MsgBox(WARNING, QObject::tr("It is not possible to perform a merging involving more than one level per column."));
			return;
		}

		if (!mLevel)
			mLevel = mCell[i].getSimpleLevel();
		else if (mLevel != mCell[i].getSimpleLevel()) {
			MsgBox(WARNING, QObject::tr("It is not possible to perform a merging involving more than one level per column."));
			return;
		}
		TImageP img = cell[i].getImage(true);
		TImageP match = mCell[i].getImage(false);
		TFrameId fid = cell[i].m_frameId;
		TFrameId mFid = mCell[i].m_frameId;

		if (!img || !match)
			continue;

		if (alreadyDoneSet.find(fid) == alreadyDoneSet.end()) {
			TRasterImageP timg = (TRasterImageP)img;
			TRasterImageP tmatch = (TRasterImageP)match;
			TVectorImageP vimg = (TVectorImageP)img;
			TVectorImageP vmatch = (TVectorImageP)match;

			if (timg) {
				if (!tmatch) {
					MsgBox(WARNING, QObject::tr("Only raster levels can be merged to a raster level."));
					return;
				}
				areRasters = true;
			} else if (vimg) {
				if (!vmatch) {
					MsgBox(WARNING, QObject::tr("Only vector levels can be merged to a vector level."));
					return;
				}
			} else {
				MsgBox(WARNING, QObject::tr("It is possible to merge only Toonz vector levels or standard raster levels."));
				return;
			}

			QString id = "MergeColumnsUndo" + QString::number(MergeColumnsSessionId) + "-" + QString::number(fid.getNumber());
			TImageCache::instance()->add(id, (timg) ? timg->cloneImage() : vimg->cloneImage());
			images[fid] = id;
			TAffine imgAff, matchAff;
			getColumnPlacement(imgAff, xsh, start + i, column, false);
			getColumnPlacement(matchAff, xsh, start + i, mColumn, false);
			TAffine dpiAff = getDpiAffine(level, fid);
			TAffine mdpiAff = getDpiAffine(mLevel, mFid);
			matchingLevels.push_back(MatchlinePair(cell[i], imgAff * dpiAff, mCell[i], matchAff * mdpiAff));
			alreadyDoneSet.insert(fid);
		}
	}

	if (matchingLevels.empty()) {
		MsgBox(WARNING, QObject::tr("It is possible to merge only Toonz vector levels or standard raster levels."));
		return;
	}

	ToonzScene *sc = TApp::instance()->getCurrentScene()->getScene();
	TXshSimpleLevel *simpleLevel = sc->getLevelSet()->getLevel(column)->getSimpleLevel();

	if (!isRedo)
		TUndoManager::manager()->add(new MergeColumnsUndo(xl, MergeColumnsSessionId,
														  column, level, images,
														  mColumn, level->getPalette()));

	if (areRasters) {
		mergeRasterColumns(matchingLevels);
		for (int i = 0; i < (int)cell.size(); i++) //the saveboxes must be updated
		{
			if (cell[i].isEmpty() || mCell[i].isEmpty())
				continue;

			if (!cell[i].getImage(false) || !mCell[i].getImage(false))
				continue;

			ToolUtils::updateSaveBox(cell[i].getSimpleLevel(), cell[i].m_frameId);
		}
	} else
		mergeVectorColumns(matchingLevels);

	TXshLevel *sl = TApp::instance()->getCurrentScene()->getScene()->getLevelSet()->getLevel(column);
	vector<TFrameId> fidsss;
	sl->getFids(fidsss);
	invalidateIcons(sl, fidsss);
	sl->setDirtyFlag(true);
	level->setDirtyFlag(true);
	TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}
Example #5
0
void mergeCmapped(int column, int mColumn, const QString &fullpath, bool isRedo)
{
	static int MergeCmappedSessionId = 0;
	MergeCmappedSessionId++;

	TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
	int start, end;
	int mStart, mEnd;
	xsh->getCellRange(column, start, end);
	xsh->getCellRange(mColumn, mStart, mEnd);

	if (start > end)
		return;
	vector<TXshCell> cell(max(end, mEnd) - min(start, mStart) + 1);
	vector<TXshCell> mCell(cell.size());

	xsh->getCells(min(start, mStart), column, cell.size(), &(cell[0]));

	if (mColumn != -1)
		xsh->getCells(min(start, mStart), mColumn, cell.size(), &(mCell[0]));

	TXshColumn *col = xsh->getColumn(column);
	TXshColumn *mcol = xsh->getColumn(mColumn);

	vector<MergeCmappedPair> matchingLevels;

	std::map<MergedPair, TFrameId> computedMergedMap;

	TXshSimpleLevel *level = 0, *mLevel = 0;
	TXshLevel *xl;

	std::map<TFrameId, QString> images;
	double dpix = 0, dpiy = 0;
	for (int i = 0; i < (int)cell.size(); i++) {
		if (!cell[i].isEmpty() && dpix == 0)
			((TToonzImageP)(cell[i].getImage(false)))->getDpi(dpix, dpiy);

		if (!level) {
			level = cell[i].getSimpleLevel();
			xl = cell[i].m_level.getPointer();
		}
		if (!mLevel)
			mLevel = mCell[i].getSimpleLevel();
	}

	if (!level || !mLevel)
		return;

	TFilePath fp(fullpath.toStdString());

	TXshLevel *txl = level->getScene()->createNewLevel(level->getType(), fp.getWideName(), level->getResolution());
	TXshSimpleLevel *newLevel = txl->getSimpleLevel();
	newLevel->setPalette(level->getPalette());
	newLevel->clonePropertiesFrom(level);
	newLevel->setPath(fp);

	TApp::instance()->getCurrentScene()->notifySceneChanged();
	TApp::instance()->getCurrentScene()->notifyCastChange();
	TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();

	int count = 0;
	for (int i = 0; i < (int)cell.size(); i++) {
		if (cell[i].isEmpty() && mCell[i].isEmpty())
			continue;

		TAffine imgAff, matchAff;

		getColumnPlacement(imgAff, xsh, min(start, mStart) + i, column, false);
		getColumnPlacement(matchAff, xsh, min(start, mStart) + i, mColumn, false);

		//std::map<TFrameId, TFrameId>::iterator it;
		MergedPair mp(cell[i].isEmpty() ? TFrameId() : cell[i].getFrameId(),
					  mCell[i].isEmpty() ? TFrameId() : mCell[i].getFrameId(),
					  imgAff.inv() * matchAff);

		std::map<MergedPair, TFrameId>::iterator computedMergedIt = computedMergedMap.find(mp);

		if (computedMergedIt != computedMergedMap.end()) {
			TXshCell newCell(newLevel, computedMergedIt->second);
			xsh->setCell(i, column, newCell);
			cell[i] = newCell;
			continue;
		}

		TFrameId newFid(++count); //level->getLastFid().getNumber()+1);
		TDimension dim = level->getResolution();
		TToonzImageP newImage;
		if (cell[i].isEmpty()) {
			newImage = TToonzImageP(TRasterCM32P(dim), TRect(0, 0, dim.lx - 1, dim.ly - 1));
			newImage->setDpi(dpix, dpiy);
		} else
			newImage = (TToonzImageP)(cell[i].getImage(false)->cloneImage());

		newImage->setPalette(level->getPalette());

		newLevel->setFrame(newFid, newImage);
		TXshCell newCell(newLevel, newFid);
		xsh->setCell(i, column, newCell);
		computedMergedMap[mp] = newCell.getFrameId();

		cell[i] = newCell;

		TImageP img = cell[i].getImage(true);
		TImageP match = mCell[i].getImage(true);
		TFrameId fid = cell[i].m_frameId;
		TFrameId mFid = mCell[i].m_frameId;

		if (!img || !match)
			continue;

		TToonzImageP timg = (TToonzImageP)img;
		TToonzImageP tmatch = (TToonzImageP)match;

		QString id = "MergeCmappedUndo" + QString::number(MergeCmappedSessionId) + "-" + QString::number(fid.getNumber());
		TImageCache::instance()->add(id, timg->clone());
		images[fid] = id;

		TAffine dpiAff = getDpiAffine(level, fid);
		TAffine mdpiAff = getDpiAffine(mLevel, mFid);
		matchingLevels.push_back(MergeCmappedPair(cell[i], imgAff * dpiAff, mCell[i], matchAff * mdpiAff));
	}

	if (!isRedo) {
		TPalette *plt = level->getPalette();

		TPaletteHandle *pltHandle = new TPaletteHandle();
		pltHandle->setPalette(plt);
		int styleCount = plt->getStyleCount();

		TUndoManager::manager()->add(new MergeCmappedUndo(txl, MergeCmappedSessionId,
														  column,
														  level, images,
														  mColumn,
														  plt));
	}

	removeLevel(xl);
	QApplication::setOverrideCursor(Qt::WaitCursor);
	mergeCmapped(matchingLevels);
	QApplication::restoreOverrideCursor();

	for (int i = 0; i < (int)cell.size(); i++) //the saveboxes must be updated
	{
		if (cell[i].isEmpty() || mCell[i].isEmpty())
			continue;

		if (!cell[i].getImage(false) || !mCell[i].getImage(false))
			continue;

		TXshSimpleLevel *sl = cell[i].getSimpleLevel();
		const TFrameId &fid = cell[i].m_frameId;

		ToolUtils::updateSaveBox(sl, fid);
		IconGenerator::instance()->invalidate(sl, fid);
		sl->setDirtyFlag(true);
	}

	newLevel->setDirtyFlag(true);
	TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}