Fix implicit merging creating explicit cells
This commit is contained in:
parent
59a90d83a8
commit
36fcc8cb90
10 changed files with 113 additions and 80 deletions
|
@ -365,7 +365,8 @@ Set cell in \b row to \b TXshCell \b cell.
|
|||
Set \b cells[] from \b row to \b row + \b rowCount to column cells.
|
||||
\sa getCell and setCells()
|
||||
*/
|
||||
virtual void getCells(int row, int rowCount, TXshCell cells[]);
|
||||
virtual void getCells(int row, int rowCount, TXshCell cells[],
|
||||
bool implicitLookup = false);
|
||||
/*!
|
||||
Set column cells from \b row to \b row + \b rowCount to cells[].
|
||||
\sa setCell() and getCell(); return false if cannot set cells[].
|
||||
|
|
|
@ -208,7 +208,8 @@ public:
|
|||
TXshCellColumn set \b \e cells[] to \b \e rowCount empty cells.
|
||||
\sa getCells(), setCells(), getCell()
|
||||
*/
|
||||
void getCells(int row, int col, int rowCount, TXshCell cells[]) const;
|
||||
void getCells(int row, int col, int rowCount, TXshCell cells[],
|
||||
bool implicitLookup = false) const;
|
||||
/*! If column identified by index \b \e col is a \b TXshCellColumn or is empty
|
||||
and is not
|
||||
locked, this method sets to \b \e cells[] the given \b \e rowCount cells of
|
||||
|
|
|
@ -31,61 +31,61 @@ class TFilePath;
|
|||
//=============================================================================
|
||||
|
||||
class ColumnLevel {
|
||||
TXshSoundLevelP m_soundLevel;
|
||||
TXshSoundLevelP m_soundLevel;
|
||||
|
||||
/*!Offsets: in frames. Start offset is a positive number.*/
|
||||
int m_startOffset;
|
||||
/*!Offsets: in frames. End offset is a positive number(to subtract to..).*/
|
||||
int m_endOffset;
|
||||
/*!Offsets: in frames. Start offset is a positive number.*/
|
||||
int m_startOffset;
|
||||
/*!Offsets: in frames. End offset is a positive number(to subtract to..).*/
|
||||
int m_endOffset;
|
||||
|
||||
//! Starting frame in the timeline
|
||||
int m_startFrame;
|
||||
//! Starting frame in the timeline
|
||||
int m_startFrame;
|
||||
|
||||
//! frameRate
|
||||
double m_fps;
|
||||
//! frameRate
|
||||
double m_fps;
|
||||
|
||||
public:
|
||||
ColumnLevel(TXshSoundLevel* soundLevel = 0, int startFrame = -1,
|
||||
int startOffset = -1, int endOffset = -1, double fps = -1);
|
||||
~ColumnLevel();
|
||||
ColumnLevel* clone() const;
|
||||
ColumnLevel(TXshSoundLevel* soundLevel = 0, int startFrame = -1,
|
||||
int startOffset = -1, int endOffset = -1, double fps = -1);
|
||||
~ColumnLevel();
|
||||
ColumnLevel* clone() const;
|
||||
|
||||
//! Overridden from TXshLevel
|
||||
TXshSoundLevel* getSoundLevel() const { return m_soundLevel.getPointer(); }
|
||||
void setSoundLevel(TXshSoundLevelP level) { m_soundLevel = level; }
|
||||
//! Overridden from TXshLevel
|
||||
TXshSoundLevel* getSoundLevel() const { return m_soundLevel.getPointer(); }
|
||||
void setSoundLevel(TXshSoundLevelP level) { m_soundLevel = level; }
|
||||
|
||||
void loadData(TIStream& is);
|
||||
void saveData(TOStream& os);
|
||||
void loadData(TIStream& is);
|
||||
void saveData(TOStream& os);
|
||||
|
||||
void setStartOffset(int value);
|
||||
int getStartOffset() const { return m_startOffset; }
|
||||
void setStartOffset(int value);
|
||||
int getStartOffset() const { return m_startOffset; }
|
||||
|
||||
void setEndOffset(int value);
|
||||
int getEndOffset() const { return m_endOffset; }
|
||||
void setEndOffset(int value);
|
||||
int getEndOffset() const { return m_endOffset; }
|
||||
|
||||
void setOffsets(int startOffset, int endOffset);
|
||||
void setOffsets(int startOffset, int endOffset);
|
||||
|
||||
//! Return the starting frame without offsets.
|
||||
void setStartFrame(int frame) { m_startFrame = frame; }
|
||||
int getStartFrame() const { return m_startFrame; }
|
||||
//! Return the starting frame without offsets.
|
||||
void setStartFrame(int frame) { m_startFrame = frame; }
|
||||
int getStartFrame() const { return m_startFrame; }
|
||||
|
||||
//! Return the ending frame without offsets.
|
||||
int getEndFrame() const;
|
||||
//! Return the ending frame without offsets.
|
||||
int getEndFrame() const;
|
||||
|
||||
//! Return frame count without offset.
|
||||
int getFrameCount() const;
|
||||
//! Return frame count without offset.
|
||||
int getFrameCount() const;
|
||||
|
||||
//! Return frame count with offset.
|
||||
int getVisibleFrameCount() const;
|
||||
//! Return frame count with offset.
|
||||
int getVisibleFrameCount() const;
|
||||
|
||||
//! Return start frame with offset.
|
||||
int getVisibleStartFrame() const;
|
||||
//! Return last frame with offset.
|
||||
int getVisibleEndFrame() const;
|
||||
//! Updates m_startOfset and m_endOffset.
|
||||
void updateFrameRate(double newFrameRate);
|
||||
//! Return start frame with offset.
|
||||
int getVisibleStartFrame() const;
|
||||
//! Return last frame with offset.
|
||||
int getVisibleEndFrame() const;
|
||||
//! Updates m_startOfset and m_endOffset.
|
||||
void updateFrameRate(double newFrameRate);
|
||||
|
||||
void setFrameRate(double fps) { m_fps = fps; }
|
||||
void setFrameRate(double fps) { m_fps = fps; }
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
@ -139,7 +139,8 @@ public:
|
|||
|
||||
const TXshCell &getCell(int row, bool implicitLookup = false) const override;
|
||||
TXshCell getSoundCell(int row);
|
||||
void getCells(int row, int rowCount, TXshCell cells[]) override;
|
||||
void getCells(int row, int rowCount, TXshCell cells[],
|
||||
bool implicitLookup = false) override;
|
||||
|
||||
bool setCell(int row, const TXshCell &cell) override;
|
||||
/*! Return false if cannot set cells.*/
|
||||
|
|
|
@ -218,8 +218,8 @@ static bool canMergeColumns(int column, int mColumn, bool forMatchlines) {
|
|||
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]));
|
||||
xsh->getCells(start, column, cell.size(), &(cell[0]), true);
|
||||
xsh->getCells(start, mColumn, cell.size(), &(mCell[0]), true);
|
||||
|
||||
TXshSimpleLevel *level = 0, *mLevel = 0;
|
||||
TXshLevelP xl;
|
||||
|
|
|
@ -328,13 +328,13 @@ void doCloneLevelNoSave(const TCellSelection::Range &range,
|
|||
|
||||
// OverwriteDialog* dialog = new OverwriteDialog();
|
||||
for (int r = range.m_r0; r <= range.m_r1; ++r) {
|
||||
TXshCell cell = xsh->getCell(r, c);
|
||||
|
||||
TImageP img = cell.getImage(true);
|
||||
if (!img) continue;
|
||||
TXshCell cell = xsh->getCell(r, c, false);
|
||||
|
||||
fid = cell.getFrameId();
|
||||
|
||||
TImageP img = cell.getImage(true);
|
||||
if (!img && !fid.isStopFrame()) continue;
|
||||
|
||||
if (cell.getSimpleLevel() == 0 ||
|
||||
cell.getSimpleLevel()->getPath().getType() == "psd" ||
|
||||
cell.getSimpleLevel()->getPath().getType() == "gif" ||
|
||||
|
@ -380,12 +380,12 @@ void doCloneLevelNoSave(const TCellSelection::Range &range,
|
|||
cell.m_level = xl;
|
||||
int k;
|
||||
for (k = range.m_r0; k < r; k++) {
|
||||
if (xsh->getCell(k, c).getImage(true).getPointer() ==
|
||||
if (xsh->getCell(k, c, false).getImage(true).getPointer() ==
|
||||
img.getPointer()) {
|
||||
TFrameId oldFid = xsh->getCell(k, c).getFrameId();
|
||||
TFrameId oldFid = xsh->getCell(k, c, false).getFrameId();
|
||||
assert(fid == oldFid);
|
||||
sl->setFrame(fid,
|
||||
xsh->getCell(k, c + range.getColCount()).getImage(true));
|
||||
xsh->getCell(k, c + range.getColCount(), false).getImage(true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -478,7 +478,7 @@ public:
|
|||
|
||||
TFilePath newLevelPath;
|
||||
TXshCell c = TApp::instance()->getCurrentXsheet()->getXsheet()->getCell(
|
||||
cells.m_r0, destColumn);
|
||||
cells.m_r0, destColumn, false);
|
||||
if (!c.isEmpty() && c.getSimpleLevel())
|
||||
newLevelPath = c.getSimpleLevel()->getPath();
|
||||
|
||||
|
|
|
@ -462,10 +462,11 @@ void mergeCmapped(int column, int mColumn, const QString &fullpath,
|
|||
std::vector<TXshCell> cell(std::max(end, mEnd) - std::min(start, mStart) + 1);
|
||||
std::vector<TXshCell> mCell(cell.size());
|
||||
|
||||
xsh->getCells(std::min(start, mStart), column, cell.size(), &(cell[0]));
|
||||
xsh->getCells(std::min(start, mStart), column, cell.size(), &(cell[0]), true);
|
||||
|
||||
if (mColumn != -1)
|
||||
xsh->getCells(std::min(start, mStart), mColumn, cell.size(), &(mCell[0]));
|
||||
xsh->getCells(std::min(start, mStart), mColumn, cell.size(), &(mCell[0]),
|
||||
true);
|
||||
|
||||
TXshColumn *col = xsh->getColumn(column);
|
||||
TXshColumn *mcol = xsh->getColumn(mColumn);
|
||||
|
@ -506,9 +507,23 @@ void mergeCmapped(int column, int mColumn, const QString &fullpath,
|
|||
TApp::instance()->getCurrentScene()->notifyCastChange();
|
||||
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
|
||||
|
||||
bool isImplicitHoldEnabled = Preferences::instance()->isImplicitHoldEnabled();
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < (int)cell.size(); i++) {
|
||||
if (cell[i].isEmpty() && mCell[i].isEmpty()) continue;
|
||||
if (cell[i].getFrameId().isStopFrame() &&
|
||||
mCell[i].getFrameId().isStopFrame())
|
||||
continue;
|
||||
|
||||
if (isImplicitHoldEnabled) {
|
||||
bool cellImplicit =
|
||||
xsh->isImplicitCell(std::min(start, mStart) + i, column);
|
||||
bool mCellImplicit =
|
||||
xsh->isImplicitCell(std::min(start, mStart) + i, mColumn);
|
||||
if (cellImplicit && (mCellImplicit || mCell[i].isEmpty())) continue;
|
||||
if (mCellImplicit && (cellImplicit || cell[i].isEmpty())) continue;
|
||||
}
|
||||
|
||||
TAffine imgAff, matchAff;
|
||||
|
||||
|
@ -516,10 +531,11 @@ void mergeCmapped(int column, int mColumn, const QString &fullpath,
|
|||
getColumnPlacement(matchAff, xsh, std::min(start, mStart) + i, mColumn,
|
||||
false);
|
||||
|
||||
TFrameId frameId = cell[i].isEmpty() ? TFrameId() : cell[i].getFrameId();
|
||||
TFrameId mFrameId = mCell[i].isEmpty() ? TFrameId() : mCell[i].getFrameId();
|
||||
|
||||
// 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);
|
||||
MergedPair mp(frameId, mFrameId, imgAff.inv() * matchAff);
|
||||
|
||||
std::map<MergedPair, TFrameId>::iterator computedMergedIt =
|
||||
computedMergedMap.find(mp);
|
||||
|
@ -534,7 +550,7 @@ void mergeCmapped(int column, int mColumn, const QString &fullpath,
|
|||
TFrameId newFid(++count); // level->getLastFid().getNumber()+1);
|
||||
TDimension dim = level->getResolution();
|
||||
TToonzImageP newImage;
|
||||
if (cell[i].isEmpty()) {
|
||||
if (cell[i].isEmpty() || cell[i].getFrameId().isStopFrame()) {
|
||||
newImage =
|
||||
TToonzImageP(TRasterCM32P(dim), TRect(0, 0, dim.lx - 1, dim.ly - 1));
|
||||
newImage->setDpi(dpix, dpiy);
|
||||
|
|
|
@ -291,7 +291,7 @@ void mergeColumns(int column, int mColumn, bool isRedo, bool groupLevels) {
|
|||
|
||||
xsh->getCells(start, column, cell.size(), &(cell[0]));
|
||||
|
||||
xsh->getCells(start, mColumn, cell.size(), &(mCell[0]));
|
||||
xsh->getCells(start, mColumn, cell.size(), &(mCell[0]), true);
|
||||
|
||||
TXshColumn *col = xsh->getColumn(column);
|
||||
TXshColumn *mcol = xsh->getColumn(mColumn);
|
||||
|
|
|
@ -162,7 +162,8 @@ void TXshCellColumn::checkColumn() const {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TXshCellColumn::getCells(int row, int rowCount, TXshCell cells[]) {
|
||||
void TXshCellColumn::getCells(int row, int rowCount, TXshCell cells[],
|
||||
bool implicitLookup) {
|
||||
const TXshCell emptyCell;
|
||||
int first = m_first;
|
||||
int i;
|
||||
|
@ -189,9 +190,20 @@ void TXshCellColumn::getCells(int row, int rowCount, TXshCell cells[]) {
|
|||
TXshCell *endDstCell = dstCell + dst;
|
||||
while (dstCell < endDstCell) *dstCell++ = emptyCell;
|
||||
endDstCell += n;
|
||||
while (dstCell < endDstCell) *dstCell++ = m_cells[src++];
|
||||
while (dstCell < endDstCell) {
|
||||
TXshCell cell = m_cells[src];
|
||||
if (cell.isEmpty() && implicitLookup) cell = getCell(src + dst);
|
||||
*dstCell++ = cell;
|
||||
src++;
|
||||
}
|
||||
endDstCell = cells + rowCount;
|
||||
while (dstCell < endDstCell) *dstCell++ = emptyCell;
|
||||
while (dstCell < endDstCell) {
|
||||
TXshCell cell = m_cells[cellCount - 1];
|
||||
if (implicitLookup && !cell.getFrameId().isStopFrame())
|
||||
*dstCell++ = cell;
|
||||
else
|
||||
*dstCell++ = emptyCell;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -325,7 +325,8 @@ bool TXsheet::setCell(int row, int col, const TXshCell &cell) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TXsheet::getCells(int row, int col, int rowCount, TXshCell cells[]) const {
|
||||
void TXsheet::getCells(int row, int col, int rowCount, TXshCell cells[],
|
||||
bool implicitLookup) const {
|
||||
static const TXshCell emptyCell;
|
||||
int i;
|
||||
TXshColumnP column = m_imp->m_columnSet.getColumn(col);
|
||||
|
@ -338,7 +339,7 @@ void TXsheet::getCells(int row, int col, int rowCount, TXshCell cells[]) const {
|
|||
for (i = 0; i < rowCount; i++) cells[i] = emptyCell;
|
||||
return;
|
||||
}
|
||||
xshColumn->getCells(row, rowCount, cells);
|
||||
xshColumn->getCells(row, rowCount, cells, implicitLookup);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -328,10 +328,10 @@ const TXshCell &TXshSoundColumn::getCell(int row, bool implicitLookup) const {
|
|||
if (!l) return emptyCell;
|
||||
TXshSoundLevel *soundLevel = l->getSoundLevel();
|
||||
TXshCell *cell = new TXshCell(soundLevel, TFrameId(row - l->getStartFrame()));
|
||||
// The new cell adds a reference to the TXshSoundLevel;
|
||||
// since the cells of the TXshSoundColumn are not persistent structures
|
||||
// but are dynamic structures (they are recreated every time) I have to take
|
||||
// care of making the release otherwise the TXshSoundLevel is never thrown
|
||||
// The new cell adds a reference to the TXshSoundLevel;
|
||||
// since the cells of the TXshSoundColumn are not persistent structures
|
||||
// but are dynamic structures (they are recreated every time) I have to take
|
||||
// care of making the release otherwise the TXshSoundLevel is never thrown
|
||||
// away.
|
||||
soundLevel->release();
|
||||
return *cell;
|
||||
|
@ -340,18 +340,18 @@ const TXshCell &TXshSoundColumn::getCell(int row, bool implicitLookup) const {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
TXshCell TXshSoundColumn::getSoundCell(int row) {
|
||||
static TXshCell emptyCell;
|
||||
static TXshCell emptyCell;
|
||||
|
||||
ColumnLevel* l = getColumnLevelByFrame(row);
|
||||
if (row < 0 || row < getFirstRow() || row > getMaxFrame()) {
|
||||
if (l) emptyCell.m_level = l->getSoundLevel();
|
||||
return emptyCell;
|
||||
}
|
||||
ColumnLevel* l = getColumnLevelByFrame(row);
|
||||
if (row < 0 || row < getFirstRow() || row > getMaxFrame()) {
|
||||
if (l) emptyCell.m_level = l->getSoundLevel();
|
||||
return emptyCell;
|
||||
}
|
||||
|
||||
if (!l) return emptyCell;
|
||||
TXshSoundLevel* soundLevel = l->getSoundLevel();
|
||||
TXshCell cell(soundLevel, TFrameId(row - l->getStartFrame()));
|
||||
return cell;
|
||||
if (!l) return emptyCell;
|
||||
TXshSoundLevel* soundLevel = l->getSoundLevel();
|
||||
TXshCell cell(soundLevel, TFrameId(row - l->getStartFrame()));
|
||||
return cell;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -391,7 +391,8 @@ void TXshSoundColumn::checkColumn() const {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TXshSoundColumn::getCells(int row, int rowCount, TXshCell cells[]) {
|
||||
void TXshSoundColumn::getCells(int row, int rowCount, TXshCell cells[],
|
||||
bool implicitLookup) {
|
||||
// le celle da settare sono [ra, rb]
|
||||
int ra = row;
|
||||
int rb = row + rowCount - 1;
|
||||
|
@ -987,7 +988,7 @@ TSoundTrackP TXshSoundColumn::getOverallSoundTrack(int fromFrame, int toFrame,
|
|||
#else
|
||||
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
|
||||
if (info.deviceName().length() == 0) throw TSoundDeviceException(TSoundDeviceException::NoDevice,
|
||||
"No device found, check QAudio backends");
|
||||
"No device found, check QAudio backends");
|
||||
QList<int> ssrs = info.supportedSampleRates();
|
||||
if (!ssrs.contains(format.m_sampleRate)) format.m_sampleRate = 44100;
|
||||
QAudioFormat qFormat;
|
||||
|
|
Loading…
Reference in a new issue