Bring in OpenToonz updates as of 10/20 (#400)

* fix saving fx ports

Signed-off-by: Jeremy Bullock <jcbullock@gmail.com>

* fix palette gizmo target

Signed-off-by: Jeremy Bullock <jcbullock@gmail.com>

* export subxsheet column to xdts

Signed-off-by: Jeremy Bullock <jcbullock@gmail.com>

* fix particles fx with sub xsheet control

Signed-off-by: Jeremy Bullock <jcbullock@gmail.com>

* fix crash on reverting scene

Signed-off-by: Jeremy Bullock <jcbullock@gmail.com>

* Fix crash on closing Tahoma with a floating level strip.

Co-authored-by: shun-iwasawa <shun.iwasawa@ghibli.jp>
This commit is contained in:
Jeremy Bullock 2020-10-21 15:00:03 -06:00 committed by GitHub
parent fe1084fcc0
commit 6954f4d14c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 61 deletions

View file

@ -873,11 +873,10 @@ void TFx::saveData(TOStream &os) {
}
os.openChild("ports");
for (PortTable::iterator pit = m_imp->m_portTable.begin();
pit != m_imp->m_portTable.end(); ++pit) {
os.openChild(pit->first);
if (pit->second->isConnected())
os << TFxP(pit->second->getFx()).getPointer();
for (auto &namePort : m_imp->m_portArray) {
os.openChild(namePort.first);
if (namePort.second->isConnected())
os << TFxP(namePort.second->getFx()).getPointer();
os.closeChild();
}
os.closeChild();

View file

@ -238,11 +238,11 @@ int FilmstripFrames::getOneFrameWidth() {
//-----------------------------------------------------------------------------
void FilmstripFrames::updateContentHeight(int minimumHeight) {
if (minimumHeight < 0)
minimumHeight = visibleRegion().boundingRect().bottom();
minimumHeight = visibleRegion().boundingRect().bottom();
int contentHeight = getFramesHeight();
if (contentHeight < minimumHeight) contentHeight = minimumHeight;
int parentHeight = parentWidget()->height();
if (contentHeight < parentHeight) contentHeight = parentHeight;
int parentHeight = parentWidget()->height();
if (contentHeight < parentHeight) contentHeight = parentHeight;
if (contentHeight != height()) setFixedHeight(contentHeight);
}
@ -250,10 +250,10 @@ void FilmstripFrames::updateContentHeight(int minimumHeight) {
void FilmstripFrames::updateContentWidth(int minimumWidth) {
setFixedHeight(getOneFrameHeight());
if (minimumWidth < 0) minimumWidth = visibleRegion().boundingRect().right();
int contentWidth = getFramesWidth();
int contentWidth = getFramesWidth();
if (contentWidth < minimumWidth) contentWidth = minimumWidth;
int parentWidth = parentWidget()->width();
if (contentWidth < parentWidth) contentWidth = parentWidth;
int parentWidth = parentWidget()->width();
if (contentWidth < parentWidth) contentWidth = parentWidth;
if (contentWidth != width()) setFixedWidth(contentWidth);
}
@ -486,7 +486,11 @@ void FilmstripFrames::hideEvent(QHideEvent *) {
// active viewer change
disconnect(app, SIGNAL(activeViewerChanged()), this, SLOT(getViewer()));
if (m_viewer) {
// if the level strip is floating during shutting down Tahoma2D
// it can cause a crash disconnecting from the viewer which was already
// destroyed. Checking the fps is a janky way to ensure the viewer is
// stil relevant.
if (m_viewer && m_viewer->getFPS() > -100) {
disconnect(m_viewer, SIGNAL(onZoomChanged()), this, SLOT(update()));
disconnect(m_viewer, SIGNAL(refreshNavi()), this, SLOT(update()));
m_viewer = nullptr;
@ -602,9 +606,8 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) {
QRectF naviRatio(
(-(float)m_viewer->width() * 0.5f - (float)imgBottomLeft.x) /
imgSizeInViewer.width(),
1.0f -
((float)m_viewer->height() * 0.5f - (float)imgBottomLeft.y) /
imgSizeInViewer.height(),
1.0f - ((float)m_viewer->height() * 0.5f - (float)imgBottomLeft.y) /
imgSizeInViewer.height(),
(float)m_viewer->width() / imgSizeInViewer.width(),
(float)m_viewer->height() / imgSizeInViewer.height());
@ -629,7 +632,7 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) {
int frameCount = (int)fids.size();
bool isReadOnly = false;
bool isReadOnly = false;
if (sl) isReadOnly = sl->isReadOnly();
int i;
@ -960,17 +963,17 @@ void FilmstripFrames::mousePressEvent(QMouseEvent *event) {
//-----------------------------------------------------------------------------
void FilmstripFrames::execNavigatorPan(const QPoint &point) {
int index = y2index(point.y());
int index = y2index(point.y());
if (!m_isVertical) index = x2index(point.x());
TFrameId fid = index2fid(index);
int i0 = y2index(0);
if (!m_isVertical) i0 = x2index(0);
TFrameId fid = index2fid(index);
int i0 = y2index(0);
if (!m_isVertical) i0 = x2index(0);
int frameHeight = m_iconSize.height() + fs_frameSpacing + fs_iconMarginTop +
fs_iconMarginBottom;
int frameWidth = m_iconSize.width() + fs_frameSpacing + fs_iconMarginLR +
fs_leftMargin + fs_rightMargin;
QPoint clickedPos = point - QPoint(0, (index - i0) * frameHeight);
QPoint clickedPos = point - QPoint(0, (index - i0) * frameHeight);
if (!m_isVertical) clickedPos = point - QPoint((index - i0) * frameWidth, 0);
if (fid != getCurrentFrameId()) return;
@ -1015,8 +1018,8 @@ void FilmstripFrames::mouseReleaseEvent(QMouseEvent *e) {
//-----------------------------------------------------------------------------
void FilmstripFrames::mouseMoveEvent(QMouseEvent *e) {
QPoint pos = e->pos();
int index = y2index(e->pos().y());
QPoint pos = e->pos();
int index = y2index(e->pos().y());
if (!m_isVertical) index = x2index(e->pos().x());
if (e->buttons() & Qt::LeftButton || e->buttons() & Qt::MiddleButton) {
// navigator pan
@ -1038,7 +1041,7 @@ void FilmstripFrames::mouseMoveEvent(QMouseEvent *e) {
}
// autopan
int speed = getOneFrameHeight() / 64;
int speed = getOneFrameHeight() / 64;
if (!m_isVertical) speed = getOneFrameWidth() / 64;
QRect visibleRect = visibleRegion().boundingRect();
@ -1213,8 +1216,8 @@ void FilmstripFrames::timerEvent(QTimerEvent *) {
m_timerId = 0;
m_timerId = startTimer(m_timerInterval);
if (m_selecting) {
QPoint pos = mapFromGlobal(m_pos);
int index = y2index(pos.y());
QPoint pos = mapFromGlobal(m_pos);
int index = y2index(pos.y());
if (!m_isVertical) index = x2index(pos.x());
select(index, DRAG_SELECT);
showFrame(index);
@ -1598,6 +1601,7 @@ void Filmstrip::onChooseLevelComboChanged(int index) {
void Filmstrip::updateChooseLevelComboItems() {
// clear items
m_chooseLevelCombo->clear();
for (auto oldLevel : m_levels) oldLevel->release();
m_levels.clear();
std::map<TXshSimpleLevel *, TFrameId> new_workingFrames;
@ -1616,6 +1620,7 @@ void Filmstrip::updateChooseLevelComboItems() {
// register only used level in xsheet
if (!scene->getTopXsheet()->isLevelUsed(sl)) continue;
sl->addRef();
m_levels.push_back(sl);
// create new m_workingFrames map with the new levelset
@ -1689,7 +1694,10 @@ void Filmstrip::updateCurrentLevelComboItem() {
//-----------------------------------------------------------------------------
Filmstrip::~Filmstrip() {}
Filmstrip::~Filmstrip() {
for (auto level : m_levels) level->release();
m_levels.clear();
}
//-----------------------------------------------------------------------------
@ -1698,7 +1706,7 @@ void Filmstrip::showEvent(QShowEvent *) {
TXshLevelHandle *levelHandle = app->getCurrentLevel();
bool ret = connect(levelHandle, SIGNAL(xshLevelSwitched(TXshLevel *)),
SLOT(onLevelSwitched(TXshLevel *)));
ret = ret &&
ret = ret &&
connect(levelHandle, SIGNAL(xshLevelChanged()), SLOT(onLevelChanged()));
// updateWindowTitle is called in the onLevelChanged
@ -1980,7 +1988,7 @@ QString InbetweenDialog::getValue() { return m_comboBox->currentText(); }
//-----------------------------------------------------------------------------
void InbetweenDialog::setValue(const QString &value) {
int currentIndex = m_comboBox->findText(value);
int currentIndex = m_comboBox->findText(value);
if (currentIndex < 0) currentIndex = 0;
m_comboBox->setCurrentIndex(currentIndex);
}

View file

@ -600,7 +600,7 @@ void FilmstripFrameHeadGadget::drawShiftTraceMarker(QPainter &p) {
//-----------------------------------------------------------------------------
bool FilmstripFrameHeadGadget::eventFilter(QObject *obj, QEvent *e) {
if (e->type() == QEvent::Close || e->type() == QEvent::Hide) return false;
if (e->type() != QEvent::MouseButtonPress && e->type() != QEvent::MouseButtonDblClick && e->type() != QEvent::MouseMove) return false;
// shift & trace case
if (CommandManager::instance()->getAction(MI_ShiftTrace)->isChecked())

View file

@ -166,7 +166,7 @@ public:
tmpmatte = 0;
else if (tmpmatte > 255)
tmpmatte = 255;
color.m = tmpmatte;
color.m = tmpmatte;
return color;
}
};
@ -186,7 +186,7 @@ public:
tmpmatte = 0;
else if (tmpmatte > 255)
tmpmatte = 255;
color.m = tmpmatte;
color.m = tmpmatte;
return color;
}
};
@ -377,11 +377,11 @@ void modifyColor(const T &modifier) {
TUndo *undo;
TStyleSelection *selection = dynamic_cast<TStyleSelection *>(
TApp::instance()->getCurrentSelection()->getSelection());
if (selection) {
if (selection && !selection->isEmpty()) {
undo = new GizmoUndo(*selection);
getStyleIds(styleIds, *selection);
}
/*-- StyleSelectionが有効でない場合はカレントStyleを用いる --*/
// modify the current style if the style selection is not active or is empty
else {
TStyleSelection tmpSelection;
tmpSelection.setPaletteHandle(paletteHandle);

View file

@ -7,6 +7,7 @@
#include "toonz/txsheet.h"
#include "toonz/txshcell.h"
#include "toonz/txshsimplelevel.h"
#include "toonz/txshchildlevel.h"
#include "toonz/txsheethandle.h"
#include "toonz/tscenehandle.h"
#include "toonz/preferences.h"
@ -201,15 +202,17 @@ QVector<TFrameId> XdtsFieldTrackItem::getCellFrameIdTrack() const {
QString XdtsFieldTrackItem::build(TXshCellColumn *column) {
// register the firstly-found level
TXshSimpleLevel *level = nullptr;
TXshLevel *level = nullptr;
TXshCell prevCell;
int r0, r1;
column->getRange(r0, r1);
if (r0 > 0) addFrame(0, TFrameId(-1));
for (int row = r0; row <= r1; row++) {
TXshCell cell = column->getCell(row);
// try to register the level
if (!level && cell.getSimpleLevel()) level = cell.getSimpleLevel();
// try to register the level. simple levels and sub xsheet levels are
// exported
if (!level) level = cell.getSimpleLevel();
if (!level) level = cell.getChildLevel();
// if the level does not match with the registered one,
// handle as the empty cell
if (!level || cell.m_level != level) cell = TXshCell();

View file

@ -68,9 +68,11 @@ private:
int m_frame; //!< Frame this fx redirects to
TFxTimeRegion m_timeRegion; //!< Input (outer) valid column frame range
TRasterFxPort m_port; //!< Input port
TXshCellColumn *m_cellColumn;
public:
TimeShuffleFx() : TRasterFx(), m_frame(0), m_timeRegion() {
TimeShuffleFx()
: TRasterFx(), m_frame(0), m_timeRegion(), m_cellColumn(nullptr) {
addInputPort("source", m_port);
}
~TimeShuffleFx() {}
@ -81,6 +83,7 @@ public:
fx->setFrame(m_frame);
fx->setTimeRegion(getTimeRegion());
fx->setCellColumn(m_cellColumn);
return fx;
}
@ -93,12 +96,21 @@ public:
}
TFxTimeRegion getTimeRegion() const override { return m_timeRegion; }
void setCellColumn(TXshCellColumn *cellColumn) { m_cellColumn = cellColumn; }
bool canHandle(const TRenderSettings &info, double frame) override {
return true;
}
std::string getPluginId() const override { return std::string(); }
int getLevelFrame(int frame) const {
if (!m_cellColumn) return m_frame;
TXshCell cell = m_cellColumn->getCell(tfloor(frame));
assert(!cell.isEmpty());
return cell.m_frameId.getNumber() - 1;
}
void doCompute(TTile &tile, double frame,
const TRenderSettings &ri) override {
if (!m_port.isConnected()) {
@ -107,25 +119,25 @@ public:
}
// Exchange frame with the stored one
TRasterFxP(m_port.getFx())->compute(tile, m_frame, ri);
TRasterFxP(m_port.getFx())->compute(tile, getLevelFrame(frame), ri);
}
bool doGetBBox(double frame, TRectD &bbox,
const TRenderSettings &info) override {
if (!m_port.isConnected()) return false;
return TRasterFxP(m_port.getFx())->doGetBBox(m_frame, bbox, info);
return TRasterFxP(m_port.getFx())
->doGetBBox(getLevelFrame(frame), bbox, info);
}
std::string getAlias(double frame,
const TRenderSettings &info) const override {
return TRasterFx::getAlias(m_frame, info);
return TRasterFx::getAlias(getLevelFrame(frame), info);
}
void doDryCompute(TRectD &rect, double frame,
const TRenderSettings &info) override {
if (m_port.isConnected())
TRasterFxP(m_port.getFx())->dryCompute(rect, m_frame, info);
TRasterFxP(m_port.getFx())->dryCompute(rect, getLevelFrame(frame), info);
}
private:
@ -261,8 +273,9 @@ public:
}
TFxP makeFx() {
return (!m_fx) ? TFxP() : (m_aff == TAffine()) ? m_fx : TFxUtil::makeAffine(
m_fx, m_aff);
return (!m_fx)
? TFxP()
: (m_aff == TAffine()) ? m_fx : TFxUtil::makeAffine(m_fx, m_aff);
}
};
@ -272,11 +285,13 @@ public:
namespace {
TFxP timeShuffle(TFxP fx, int frame, TFxTimeRegion timeRegion) {
TFxP timeShuffle(TFxP fx, int frame, TFxTimeRegion timeRegion,
TXshCellColumn *cellColumn) {
TimeShuffleFx *timeShuffle = new TimeShuffleFx();
timeShuffle->setFrame(frame);
timeShuffle->setTimeRegion(timeRegion);
timeShuffle->setCellColumn(cellColumn);
if (!timeShuffle->connect("source", fx.getPointer()))
assert(!"Could not connect ports!");
@ -301,7 +316,7 @@ bool getColumnPlacement(TAffine &aff, TXsheet *xsh, double row, int col,
if (isPreview)
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
else
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
TStageObject *camera = xsh->getStageObject(cameraId);
TAffine cameraAff = camera->getPlacement(row);
double cameraZ = camera->getZ(row);
@ -326,7 +341,7 @@ static bool getColumnPlacement(PlacedFx &pf, TXsheet *xsh, double row, int col,
if (isPreview)
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
else
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
TStageObject *camera = xsh->getStageObject(cameraId);
TAffine cameraAff = camera->getPlacement(row);
double cameraZ = camera->getZ(row);
@ -353,7 +368,7 @@ static bool getStageObjectPlacement(TAffine &aff, TXsheet *xsh, double row,
if (isPreview)
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
else
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
TStageObject *camera = xsh->getStageObject(cameraId);
TAffine cameraAff = camera->getPlacement(row);
double cameraZ = camera->getZ(row);
@ -406,7 +421,7 @@ static TPointD getColumnSpeed(TXsheet *xsh, double row, int col,
if (isPreview)
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
else
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
TStageObject *camera = xsh->getStageObject(cameraId);
TAffine cameraAff = camera->getPlacement(row + h);
a = aff * TPointD(-cameraAff.a13, -cameraAff.a23);
@ -437,7 +452,7 @@ static QList<TPointD> getColumnMotionPoints(TXsheet *xsh, double row, int col,
if (isPreview)
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
else
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
TStageObject *camera = xsh->getStageObject(cameraId);
TAffine dpiAff = getDpiAffine(camera->getCamera());
@ -511,7 +526,7 @@ QString getNoteText(TXsheet *xsh, double row, int col, int noteColumnIndex,
return cell.getSoundTextLevel()->getFrameText(cell.m_frameId.getNumber() - 1);
}
};
}; // namespace
//***************************************************************************************************
// FxBuilder definition
@ -812,7 +827,8 @@ PlacedFx FxBuilder::makePF(TLevelColumnFx *lcfx) {
FxBuilder builder(m_scene, xsh, levelFrame, m_whichLevels, m_isPreview);
// Then, add the TimeShuffleFx
pf.m_fx = timeShuffle(builder.buildFx(), levelFrame, lcfx->getTimeRegion());
pf.m_fx = timeShuffle(builder.buildFx(), levelFrame, lcfx->getTimeRegion(),
lcfx->getColumn());
pf.m_fx->setIdentifier(lcfx->getIdentifier());
pf.m_fx->getAttributes()->passiveCacheDataIdx() =
lcfx->getAttributes()->passiveCacheDataIdx();
@ -925,10 +941,10 @@ PlacedFx FxBuilder::makePF(TZeraryColumnFx *zcfx) {
// Build
PlacedFx pf;
pf.m_columnIndex = zcfx->getColumn()->getIndex();
pf.m_fx = fx->clone(
false); // Detach the fx with a clone. Why? It's typically done to
// build fx connections in the render-tree freely. Here, it's
// used just for particles, I guess...
pf.m_fx =
fx->clone(false); // Detach the fx with a clone. Why? It's typically done
// to build fx connections in the render-tree freely.
// Here, it's used just for particles, I guess...
// Deal with input sub-trees
for (int i = 0; i < fx->getInputPortCount(); ++i) {
// Note that only particles should end up here, currently
@ -1126,7 +1142,7 @@ TFxP buildSceneFx(ToonzScene *scene, TXsheet *xsh, double row, int whichLevels,
if (isPreview)
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
else
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
TStageObject *cameraPegbar = xsh->getStageObject(cameraId);
assert(cameraPegbar);
TCamera *camera = cameraPegbar->getCamera();
@ -1198,7 +1214,7 @@ DVAPI TFxP buildPartialSceneFx(ToonzScene *scene, double row, const TFxP &root,
if (isPreview)
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
else
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
TStageObject *cameraPegbar = xsh->getStageObject(cameraId);
assert(cameraPegbar);
TCamera *camera = cameraPegbar->getCamera();
@ -1266,7 +1282,7 @@ DVAPI TFxP buildPostSceneFx(ToonzScene *scene, double frame, int shrink,
int whichLevels =
scene->getProperties()->getOutputProperties()->getWhichLevels();
TXsheet *xsh = scene->getXsheet();
TXsheet *xsh = scene->getXsheet();
if (!xsh) xsh = scene->getXsheet();
// Do not expand the xsheet node
@ -1278,7 +1294,7 @@ DVAPI TFxP buildPostSceneFx(ToonzScene *scene, double frame, int shrink,
if (isPreview)
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
else
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
TStageObject *cameraPegbar = xsh->getStageObject(cameraId);
assert(cameraPegbar);
TCamera *camera = cameraPegbar->getCamera();