Fix implicit merging creating explicit cells

This commit is contained in:
manongjohn 2022-03-05 22:05:24 -05:00
parent 59a90d83a8
commit 36fcc8cb90
10 changed files with 113 additions and 80 deletions

View file

@ -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[].

View file

@ -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

View file

@ -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.*/

View file

@ -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;

View file

@ -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();

View file

@ -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);

View file

@ -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);

View file

@ -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;
}
}
//-----------------------------------------------------------------------------

View file

@ -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);
}
//-----------------------------------------------------------------------------

View file

@ -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;