diff --git a/toonz/sources/include/toonz/txsheet.h b/toonz/sources/include/toonz/txsheet.h index 4dab117b..5d5a0e36 100644 --- a/toonz/sources/include/toonz/txsheet.h +++ b/toonz/sources/include/toonz/txsheet.h @@ -593,7 +593,7 @@ in TXsheetImp. bool isReferenceManagementIgnored(TDoubleParam *); void convertToImplicitHolds(); - void convertToExplicitHolds(); + void convertToExplicitHolds(int endPlayRange); NavigationTags *getNavigationTags() const { return m_navigationTags; } bool isFrameTagged(int frame) const; diff --git a/toonz/sources/toonz/previewfxmanager.cpp b/toonz/sources/toonz/previewfxmanager.cpp index efba8cef..ce186ef8 100644 --- a/toonz/sources/toonz/previewfxmanager.cpp +++ b/toonz/sources/toonz/previewfxmanager.cpp @@ -558,6 +558,9 @@ void PreviewFxInstance::updateFrameRange() { properties->getRange(m_start, m_end, m_step); if (m_end < 0) m_end = frameCount - 1; + if (m_end >= frameCount && Preferences::instance()->isImplicitHoldEnabled()) + frameCount = m_end; + // Intersect with the fx active frame range TRasterFxP rasterFx(m_fx); TFxTimeRegion timeRegion(rasterFx->getTimeRegion()); diff --git a/toonz/sources/toonz/subscenecommand.cpp b/toonz/sources/toonz/subscenecommand.cpp index e2c5a013..1df1c505 100644 --- a/toonz/sources/toonz/subscenecommand.cpp +++ b/toonz/sources/toonz/subscenecommand.cpp @@ -1283,39 +1283,6 @@ void removeFx(TXsheet *xsh, TFx *fx) { //----------------------------------------------------------------------------- -int getChildFrameCount(TXsheet *childXsh) { - if (!childXsh) return 0; - - int frameCount = childXsh->getFrameCount(); - - // For implicit holds, use last Stop Frame marker or last Key frame marker as - // frame count - if (Preferences::instance()->isImplicitHoldEnabled()) { - for (int c = 0; c < childXsh->getColumnCount(); c++) { - int r0, r1; - - r1 = childXsh->getMaxFrame(c); - TXshCell cell = childXsh->getCell(r1, c); - // If last frame is a stop frame, don't check for keyframe in the same - // column in case of overshoot - if (cell.getFrameId().isStopFrame()) { - frameCount = std::max(frameCount, (r1 + 1)); - continue; - } - - TStageObject *pegbar = - childXsh->getStageObject(TStageObjectId::ColumnId(c)); - if (!pegbar) continue; - if (!pegbar->getKeyframeRange(r0, r1)) continue; - frameCount = std::max(frameCount, (r1 + 1)); - } - } - - return frameCount; -} - -//----------------------------------------------------------------------------- - void collapseColumns(std::set indices, bool columnsOnly) { // return if there is no selected columns if (indices.empty()) return; @@ -1371,7 +1338,7 @@ void collapseColumns(std::set indices, bool columnsOnly) { xsh->insertColumn(index); // set subxsheet cells in the parent xhseet - int r, rowCount = getChildFrameCount(childXsh); + int r, rowCount = childXsh->getFrameCount(); for (r = 0; r < rowCount; ++r) xsh->setCell(r, index, TXshCell(xl, TFrameId(r + 1))); @@ -1474,7 +1441,7 @@ void collapseColumns(std::set indices, xsh->insertColumn(index); - int r, rowCount = getChildFrameCount(childXsh); + int r, rowCount = childXsh->getFrameCount(); for (r = 0; r < rowCount; r++) xsh->setCell(r, index, TXshCell(xl, TFrameId(r + 1))); @@ -1548,7 +1515,7 @@ void collapseColumns(std::set indices, const std::set &fxs, if (output) xsh->getFxDag()->removeOutputFx(output); } - int rowCount = getChildFrameCount(childXsh); + int rowCount = childXsh->getFrameCount(); int r; for (r = 0; r < rowCount; r++) xsh->setCell(r, index, TXshCell(xl, TFrameId(r + 1))); diff --git a/toonz/sources/toonz/xsheetcmd.cpp b/toonz/sources/toonz/xsheetcmd.cpp index ab56a178..a265d003 100644 --- a/toonz/sources/toonz/xsheetcmd.cpp +++ b/toonz/sources/toonz/xsheetcmd.cpp @@ -1451,7 +1451,9 @@ static void convertHoldType(int holdType) { xsh->convertToImplicitHolds(); if (action && !action->isChecked()) action->trigger(); } else { - xsh->convertToExplicitHolds(); + int r0, r1, step; + XsheetGUI::getPlayRange(r0, r1, step); + xsh->convertToExplicitHolds(r1); if (action && action->isChecked()) action->trigger(); } diff --git a/toonz/sources/toonzlib/txsheet.cpp b/toonz/sources/toonzlib/txsheet.cpp index a8f3f05c..3c022270 100644 --- a/toonz/sources/toonzlib/txsheet.cpp +++ b/toonz/sources/toonzlib/txsheet.cpp @@ -229,7 +229,40 @@ unsigned long TXsheet::id() const { return m_imp->m_id; } //----------------------------------------------------------------------------- -int TXsheet::getFrameCount() const { return m_imp->m_frameCount; } +int TXsheet::getFrameCount() const { + if (!Preferences::instance()->isImplicitHoldEnabled()) + return m_imp->m_frameCount; + + // For implicit holds, use last Stop Frame marker or last Key frame marker as + // frame count + int r0, r1; + + int frameCount = m_imp->m_frameCount; + for (int c = 0; c < getColumnCount(); c++) { + + r1 = getMaxFrame(c); + TXshCell cell = getCell(r1, c); + // If last frame is a stop frame, don't check for keyframe in the same + // column in case of overshoot + if (cell.getFrameId().isStopFrame()) { + frameCount = std::max(frameCount, r1); + continue; + } + + TStageObject *pegbar = getStageObject(TStageObjectId::ColumnId(c)); + if (!pegbar) continue; + if (!pegbar->getKeyframeRange(r0, r1)) continue; + frameCount = std::max(frameCount, (r1 + 1)); + } + + // Check camera keys + TStageObjectId cameraId = getStageObjectTree()->getCurrentCameraId(); + TStageObject *camera = getStageObject(cameraId); + if (camera && camera->getKeyframeRange(r0, r1)) + frameCount = std::max(frameCount, (r1 + 1)); + + return frameCount; +} //----------------------------------------------------------------------------- @@ -924,7 +957,8 @@ int TXsheet::reframeCells(int r0, int r1, int col, int type, int withBlank) { for (int r = r0; r <= r1; r++) { const TXshCell &cell = getCell(CellPosition(r, col)); if (cells.size() == 0 || cells.last() != cell) { - if (cell.isEmpty() && cells.last().getFrameId() == TFrameId::STOP_FRAME) + if (cell.isEmpty() && cells.size() && + cells.last().getFrameId() == TFrameId::STOP_FRAME) continue; cells.push_back(cell); } @@ -1029,7 +1063,7 @@ void TXsheet::rollupCells(int r0, int c0, int r1, int c1) { // in cells copio il contenuto delle celle che mi interessano int k; - for (k = c0; k <= c1; k++) cells[k - c0] = getCell(CellPosition(r0, k)); + for (k = c0; k <= c1; k++) cells[k - c0] = getCell(CellPosition(r0, k), false); for (k = c0; k <= c1; k++) removeCells(r0, k, 1); @@ -1052,7 +1086,7 @@ void TXsheet::rolldownCells(int r0, int c0, int r1, int c1) { // in cells copio il contenuto delle celle che mi interessano int k; - for (k = c0; k <= c1; k++) cells[k - c0] = getCell(CellPosition(r1, k)); + for (k = c0; k <= c1; k++) cells[k - c0] = getCell(CellPosition(r1, k), false); for (k = c0; k <= c1; k++) removeCells(r1, k, 1); @@ -2010,7 +2044,7 @@ void TXsheet::convertToImplicitHolds() { //--------------------------------------------------------- -void TXsheet::convertToExplicitHolds() { +void TXsheet::convertToExplicitHolds(int endPlayRange) { int cols = getColumnCount(); if (!cols) return; @@ -2030,6 +2064,10 @@ void TXsheet::convertToExplicitHolds() { if (!cc->getRange(r0, r1)) continue; int frameCount = getFrameCount() - 1; + if (endPlayRange > frameCount && + Preferences::instance()->isImplicitHoldEnabled()) + frameCount = endPlayRange; + TXshCell prevCell; r1 = std::max(r1, frameCount);