fix raster deformation slowness

This commit is contained in:
shun-iwasawa 2021-04-21 17:42:56 +09:00 committed by manongjohn
parent 9a9f34e492
commit 8c3707a1ce
8 changed files with 124 additions and 52 deletions

View file

@ -97,6 +97,7 @@ public:
QPointF m_mousePos; // mouse position obtained with QMouseEvent::pos() or
// QTabletEvent::pos()
bool m_isTablet;
bool m_isHighFrequent;
public:
TMouseEvent()
@ -104,7 +105,8 @@ public:
, m_modifiersMask(NO_KEY)
, m_buttons(Qt::NoButton)
, m_button(Qt::NoButton)
, m_isTablet(false) {}
, m_isTablet(false)
, m_isHighFrequent(false) {}
bool isShiftPressed() const { return (m_modifiersMask & SHIFT_KEY); }
bool isAltPressed() const { return (m_modifiersMask & ALT_KEY); }
@ -115,6 +117,7 @@ public:
Qt::MouseButton button() const { return m_button; }
QPointF mousePos() const { return m_mousePos; }
bool isTablet() const { return m_isTablet; }
bool isHighFrequent() const { return m_isHighFrequent; }
void setModifiers(bool shiftPressed, bool altPressed, bool ctrlPressed) {
m_modifiersMask = ModifierMask((shiftPressed << SHIFT_BITSHIFT) |

View file

@ -246,7 +246,8 @@ DragSelectionTool::RasterDeformTool::RasterDeformTool(RasterSelectionTool *tool,
//-----------------------------------------------------------------------------
void DragSelectionTool::RasterDeformTool::applyTransform(FourPoints bbox) {
void DragSelectionTool::RasterDeformTool::applyTransform(FourPoints bbox,
bool onFastDragging) {
RasterSelectionTool *tool = (RasterSelectionTool *)getTool();
tool->setNewFreeDeformer();
if (!m_deformUndo) m_deformUndo = new UndoRasterDeform(tool);
@ -257,7 +258,8 @@ void DragSelectionTool::RasterDeformTool::applyTransform(FourPoints bbox) {
RasterFreeDeformer *freeDeformer =
(RasterFreeDeformer *)tool->getFreeDeformer();
if (!freeDeformer) return;
freeDeformer->setNoAntialiasing(tool->getNoAntialiasingValue());
freeDeformer->setNoAntialiasing(tool->getNoAntialiasingValue() |
onFastDragging);
freeDeformer->setPoints(realBbox.getP00(), realBbox.getP10(),
realBbox.getP11(), realBbox.getP01());
freeDeformer->deformImage();
@ -361,6 +363,14 @@ void DragSelectionTool::RasterFreeDeformTool::leftButtonDrag(
m_freeDeform->leftButtonDrag(pos, e);
}
//-----------------------------------------------------------------------------
void DragSelectionTool::RasterFreeDeformTool::leftButtonUp(
const TPointD &pos, const TMouseEvent &e) {
m_freeDeform->leftButtonUp();
RasterDeformTool::leftButtonUp(pos, e);
}
//=============================================================================
// RasterMoveSelectionTool
//-----------------------------------------------------------------------------
@ -404,8 +414,8 @@ DragSelectionTool::RasterScaleTool::RasterScaleTool(RasterSelectionTool *tool,
//-----------------------------------------------------------------------------
TPointD DragSelectionTool::RasterScaleTool::transform(int index,
TPointD newPos) {
TPointD DragSelectionTool::RasterScaleTool::transform(int index, TPointD newPos,
bool onFastDragging) {
SelectionTool *tool = getTool();
TPointD scaleValue = tool->m_deformValues.m_scaleValue;
@ -419,7 +429,7 @@ TPointD DragSelectionTool::RasterScaleTool::transform(int index,
if (!m_scale->scaleInCenter())
tool->setCenter(m_scale->getNewCenter(index, startBboxs[0], scaleValue));
applyTransform(bbox);
applyTransform(bbox, onFastDragging);
tool->setBBox(bbox);
@ -441,6 +451,14 @@ void DragSelectionTool::RasterScaleTool::leftButtonDrag(const TPointD &pos,
m_scale->leftButtonDrag(pos, e);
}
//-----------------------------------------------------------------------------
void DragSelectionTool::RasterScaleTool::leftButtonUp(const TPointD &pos,
const TMouseEvent &e) {
m_scale->leftButtonUp();
RasterDeformTool::leftButtonUp(pos, e);
}
TEnv::IntVar ModifySavebox("ModifySavebox", 0);
TEnv::IntVar NoAntialiasing("NoAntialiasing", 0);
@ -605,9 +623,13 @@ void RasterSelectionTool::leftButtonDrag(const TPointD &pos,
invalidate();
return;
}
if (m_dragTool) {
if (!m_rasterSelection.isEditable()) return;
double pixelSize = getPixelSize();
if (m_dragTool) {
// Even in Windows version deformation is processed at interval of 20msec.
// (See SceneViewer::tabletEvent)
if (e.isHighFrequent()) return;
if (!m_rasterSelection.isEditable()) return;
m_dragTool->leftButtonDrag(pos, e);
invalidate();
return;
@ -646,7 +668,6 @@ void RasterSelectionTool::leftButtonDrag(const TPointD &pos,
return;
}
double pixelSize = getPixelSize();
TTool::Application *app = TTool::getApplication();
if (!app || m_justSelected || !m_selecting ||
tdistance2(pos, m_curPos) < 9.0 * pixelSize * pixelSize)

View file

@ -108,7 +108,7 @@ protected:
//! It's true when use RasterFreeDeformer
bool m_isFreeDeformer;
void applyTransform(FourPoints bbox) override;
void applyTransform(FourPoints bbox, bool onFastDragging = false) override;
void applyTransform(TAffine aff, bool modifyCenter);
void addTransformUndo() override;
@ -143,6 +143,7 @@ class RasterFreeDeformTool final : public RasterDeformTool {
public:
RasterFreeDeformTool(RasterSelectionTool *tool);
void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonUp(const TPointD &pos, const TMouseEvent &e) override;
};
//=============================================================================
@ -169,9 +170,11 @@ class RasterScaleTool final : public RasterDeformTool {
public:
RasterScaleTool(RasterSelectionTool *tool, ScaleType type);
/*! Return scale value. */
TPointD transform(int index, TPointD newPos) override;
TPointD transform(int index, TPointD newPos,
bool onFastDragging = false) override;
void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonUp(const TPointD &pos, const TMouseEvent &e) override;
};
} // namespace DragSelectionTool

View file

@ -22,7 +22,9 @@ TEnv::StringVar SelectionType("SelectionType", "Rectangular");
//-----------------------------------------------------------------------------
template <typename Tv, typename Tr, typename... Args> DragSelectionTool::DragTool* createNewDragTool(SelectionTool* st, Args... args) {
template <typename Tv, typename Tr, typename... Args>
DragSelectionTool::DragTool *createNewDragTool(SelectionTool *st,
Args... args) {
VectorSelectionTool *vst = dynamic_cast<VectorSelectionTool *>(st);
RasterSelectionTool *rst = dynamic_cast<RasterSelectionTool *>(st);
if (vst)
@ -33,7 +35,8 @@ template <typename Tv, typename Tr, typename... Args> DragSelectionTool::DragToo
}
DragSelectionTool::DragTool *createNewMoveSelectionTool(SelectionTool *st) {
return createNewDragTool<VectorMoveSelectionTool, RasterMoveSelectionTool>(st);
return createNewDragTool<VectorMoveSelectionTool, RasterMoveSelectionTool>(
st);
}
DragSelectionTool::DragTool *createNewRotationTool(SelectionTool *st) {
@ -44,7 +47,8 @@ DragSelectionTool::DragTool *createNewFreeDeformTool(SelectionTool *st) {
return createNewDragTool<VectorFreeDeformTool, RasterFreeDeformTool>(st);
}
DragSelectionTool::DragTool *createNewScaleTool(SelectionTool *st, ScaleType type) {
DragSelectionTool::DragTool *createNewScaleTool(SelectionTool *st,
ScaleType type) {
return createNewDragTool<VectorScaleTool, RasterScaleTool>(st, type);
}
@ -476,10 +480,13 @@ void DragSelectionTool::FreeDeform::leftButtonDrag(const TPointD &pos,
const TMouseEvent &e) {
SelectionTool *tool = m_deformTool->getTool();
TPointD delta = pos - m_deformTool->getCurPos();
TPointD center = tool->getCenter();
int index = tool->getSelectedPoint();
FourPoints bbox = tool->getBBox();
FourPoints newBbox = bbox;
double pixelSize = tool->getPixelSize();
bool isFastDragging = norm2(delta) > 9.0 * pixelSize * pixelSize;
TPointD center = tool->getCenter();
int index = tool->getSelectedPoint();
FourPoints bbox = tool->getBBox();
FourPoints newBbox = bbox;
if (index < 4)
bbox.setPoint(index, bbox.getPoint(index) + delta);
else {
@ -491,7 +498,13 @@ void DragSelectionTool::FreeDeform::leftButtonDrag(const TPointD &pos,
}
tool->setBBox(bbox);
m_deformTool->setCurPos(pos);
m_deformTool->applyTransform(bbox);
m_deformTool->applyTransform(bbox, isFastDragging);
}
//-----------------------------------------------------------------------------
void DragSelectionTool::FreeDeform::leftButtonUp() {
m_deformTool->applyTransform(m_deformTool->getTool()->getBBox());
}
//=============================================================================
@ -528,7 +541,7 @@ void DragSelectionTool::MoveSelection::leftButtonDrag(const TPointD &pos,
m_lastDelta = TPointD(0, (curPos - m_firstPos).y);
aff *= TTranslation(m_lastDelta);
} else
aff = TTranslation(delta);
aff = TTranslation(delta);
double factor = 1.0 / Stage::inch;
m_deformTool->getTool()->m_deformValues.m_moveValue =
m_deformTool->getTool()->m_deformValues.m_moveValue + factor * delta;
@ -738,7 +751,7 @@ FourPoints DragSelectionTool::Scale::bboxScaleInCenter(
if (areAlmostEqual(oldp.x, newPos.x, 1e-2) &&
areAlmostEqual(oldp.y, newPos.y, 1e-2))
return oldBbox;
FourPoints bbox = bboxScale(index, oldBbox, newPos);
FourPoints bbox = bboxScale(index, oldBbox, newPos);
if (recomputeScaleValue) scaleValue = computeScaleValue(index, bbox);
if (!m_scaleInCenter) return bbox;
int symmetricIndex = m_deformTool->getSymmetricPointIndex(index);
@ -788,7 +801,7 @@ void DragSelectionTool::Scale::leftButtonDrag(const TPointD &pos,
if (!isBboxReset)
delta = pos - m_deformTool->getCurPos();
else
delta = pos - m_deformTool->getStartPos();
delta = pos - m_deformTool->getStartPos();
int symmetricIndex = m_deformTool->getSymmetricPointIndex(selectedIndex);
TPointD symmetricPoint = tool->getBBox().getPoint(symmetricIndex);
TPointD v = normalize(point - symmetricPoint);
@ -796,12 +809,31 @@ void DragSelectionTool::Scale::leftButtonDrag(const TPointD &pos,
newPos = point + delta;
}
m_scaleInCenter = m_isAltPressed;
double pixelSize = tool->getPixelSize();
bool isFastDragging =
tdistance2(pos, m_deformTool->getCurPos()) > 9.0 * pixelSize * pixelSize;
m_deformTool->setCurPos(pos);
TPointD scaleValue = m_deformTool->transform(selectedIndex, newPos);
TPointD scaleValue =
m_deformTool->transform(selectedIndex, newPos, isFastDragging);
tool->m_deformValues.m_scaleValue = scaleValue;
TTool::getApplication()->getCurrentTool()->notifyToolChanged();
}
//-----------------------------------------------------------------------------
void DragSelectionTool::Scale::leftButtonUp() {
SelectionTool *tool = m_deformTool->getTool();
TPointD newPos = m_deformTool->getCurPos();
int selectedIndex = tool->getSelectedPoint();
if (m_isShiftPressed && m_type == ScaleType::GLOBAL) {
newPos = tool->getBBox().getPoint(selectedIndex);
}
m_deformTool->transform(selectedIndex, newPos);
TTool::getApplication()->getCurrentTool()->notifyToolChanged();
}
//=============================================================================
// SelectionTool
//-----------------------------------------------------------------------------
@ -1023,7 +1055,7 @@ void SelectionTool::updateAction(TPointD pos, const TMouseEvent &e) {
}
m_selectedPoint = NONE;
if ((isLevelType() || isSelectedFramesType()) && !isSameStyleType()) {
m_what = Inside;
m_what = Inside;
m_cursorId = ToolCursor::LevelSelectCursor;
}
@ -1133,7 +1165,7 @@ bool SelectionTool::keyDown(QKeyEvent *event) {
if (!ti && !vi && !ri) return false;
std::unique_ptr<DragTool> dragTool(createNewMoveSelectionTool(this));
TAffine aff = TTranslation(delta);
TAffine aff = TTranslation(delta);
dragTool->transform(aff);
double factor = 1.0 / Stage::inch;
m_deformValues.m_moveValue += factor * delta;

View file

@ -48,7 +48,7 @@ public:
/*! Helper function. */
virtual void setPoints(const TPointD &p0, const TPointD &p1,
const TPointD &p2, const TPointD &p3) = 0;
virtual void deformImage() = 0;
virtual void deformImage() = 0;
};
//=============================================================================
@ -152,15 +152,18 @@ public:
SelectionTool *getTool() const { return m_tool; }
virtual void transform(TAffine aff, double angle){}
virtual void transform(TAffine aff){}
virtual TPointD transform(int index, TPointD newPos) { return TPointD(); }
virtual void addTransformUndo(){}
virtual void transform(TAffine aff, double angle) {}
virtual void transform(TAffine aff) {}
virtual TPointD transform(int index, TPointD newPos,
bool onFastDragging = false) {
return TPointD();
}
virtual void addTransformUndo() {}
virtual void leftButtonDown(const TPointD &pos, const TMouseEvent &) = 0;
virtual void leftButtonDrag(const TPointD &pos, const TMouseEvent &) = 0;
virtual void leftButtonUp(const TPointD &pos, const TMouseEvent &) = 0;
virtual void draw() = 0;
virtual void draw() = 0;
};
//=============================================================================
@ -177,7 +180,7 @@ protected:
public:
DeformTool(SelectionTool *tool);
virtual void applyTransform(FourPoints bbox) = 0;
virtual void applyTransform(FourPoints bbox, bool onFastDragging = false) = 0;
virtual void applyTransform(TAffine aff){};
void addTransformUndo() override = 0;
@ -234,6 +237,7 @@ class FreeDeform {
public:
FreeDeform(DeformTool *deformTool);
void leftButtonDrag(const TPointD &pos, const TMouseEvent &e);
void leftButtonUp();
};
//=============================================================================
@ -254,11 +258,7 @@ public:
// Scale
//-----------------------------------------------------------------------------
enum class ScaleType {
GLOBAL = 0,
HORIZONTAL,
VERTICAL
};
enum class ScaleType { GLOBAL = 0, HORIZONTAL, VERTICAL };
class Scale {
TPointD m_startCenter;
@ -270,7 +270,6 @@ class Scale {
DeformTool *m_deformTool;
public:
ScaleType m_type;
Scale(DeformTool *deformTool, ScaleType type);
@ -301,12 +300,13 @@ compute scaleValue. */
void leftButtonDown(const TPointD &pos, const TMouseEvent &e);
void leftButtonDrag(const TPointD &pos, const TMouseEvent &e);
void leftButtonUp();
std::vector<FourPoints> getStartBboxs() const { return m_startBboxs; }
TPointD getStartCenter() const { return m_startCenter; }
bool scaleInCenter() const { return m_scaleInCenter; }
};
};
}; // namespace DragSelectionTool
//=============================================================================
// Utility
@ -315,7 +315,8 @@ compute scaleValue. */
DragSelectionTool::DragTool *createNewMoveSelectionTool(SelectionTool *st);
DragSelectionTool::DragTool *createNewRotationTool(SelectionTool *st);
DragSelectionTool::DragTool *createNewFreeDeformTool(SelectionTool *st);
DragSelectionTool::DragTool *createNewScaleTool(SelectionTool *st, DragSelectionTool::ScaleType type);
DragSelectionTool::DragTool *createNewScaleTool(
SelectionTool *st, DragSelectionTool::ScaleType type);
//=============================================================================
// SelectionTool
@ -420,7 +421,7 @@ public:
int index = 0);
FreeDeformer *getFreeDeformer(int index = 0) const;
virtual void setNewFreeDeformer() = 0;
virtual void setNewFreeDeformer() = 0;
void clearDeformers();
int getSelectedPoint() const { return m_selectedPoint; }

View file

@ -579,7 +579,8 @@ DragSelectionTool::VectorDeformTool::~VectorDeformTool() {
//-----------------------------------------------------------------------------
void DragSelectionTool::VectorDeformTool::applyTransform(FourPoints bbox) {
void DragSelectionTool::VectorDeformTool::applyTransform(FourPoints bbox,
bool onFastDragging) {
SelectionTool *tool = getTool();
std::unique_ptr<VFDScopedBlock> localVfdScopedBlock;
@ -852,8 +853,8 @@ DragSelectionTool::VectorScaleTool::VectorScaleTool(VectorSelectionTool *tool,
//-----------------------------------------------------------------------------
TPointD DragSelectionTool::VectorScaleTool::transform(int index,
TPointD newPos) {
TPointD DragSelectionTool::VectorScaleTool::transform(int index, TPointD newPos,
bool onFastDragging) {
SelectionTool *tool = getTool();
TPointD scaleValue = tool->m_deformValues.m_scaleValue;

View file

@ -150,7 +150,7 @@ public:
VectorDeformTool(VectorSelectionTool *tool);
~VectorDeformTool();
void applyTransform(FourPoints bbox) override;
void applyTransform(FourPoints bbox, bool onFastDragging = false) override;
void addTransformUndo() override;
/*! Transform whole level and add undo. */
@ -225,8 +225,8 @@ class VectorScaleTool final : public VectorDeformTool {
public:
VectorScaleTool(VectorSelectionTool *tool, ScaleType type);
TPointD transform(int index,
TPointD newPos) override; //!< Returns scale value.
TPointD transform(int index, TPointD newPos, bool onFastDragging = false)
override; //!< Returns scale value.
void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;

View file

@ -92,7 +92,8 @@ void initToonzEvent(TMouseEvent &toonzEvent, QMouseEvent *event,
//-----------------------------------------------------------------------------
void initToonzEvent(TMouseEvent &toonzEvent, QTabletEvent *event,
int widgetHeight, double pressure, int devPixRatio) {
int widgetHeight, double pressure, int devPixRatio,
bool isHighFrequent = false) {
toonzEvent.m_pos = TPointD(
event->posF().x() * (float)devPixRatio,
(float)widgetHeight - 1.0f - event->posF().y() * (float)devPixRatio);
@ -102,9 +103,10 @@ void initToonzEvent(TMouseEvent &toonzEvent, QTabletEvent *event,
toonzEvent.setModifiers(event->modifiers() & Qt::ShiftModifier,
event->modifiers() & Qt::AltModifier,
event->modifiers() & Qt::ControlModifier);
toonzEvent.m_buttons = event->buttons();
toonzEvent.m_button = event->button();
toonzEvent.m_isTablet = true;
toonzEvent.m_buttons = event->buttons();
toonzEvent.m_button = event->button();
toonzEvent.m_isTablet = true;
toonzEvent.m_isHighFrequent = isHighFrequent;
// this delays autosave during stylus button press until after the next
// brush stroke - this minimizes problems from interruptions to tablet input
TApp::instance()->getCurrentTool()->setToolBusy(true);
@ -364,9 +366,18 @@ void SceneViewer::tabletEvent(QTabletEvent *e) {
#if defined(_WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
// Use the application attribute Qt::AA_CompressTabletEvents instead of the
// delay timer
// 21/4/2021 High frequent tablet event caused slowness when deforming with
// Raster Selection Tool. So I re-introduced the delay timer to make
// necessary interval for it. Deformation will be processed at interval of
// 20msec. (See RasterSelectionTool::leftButtonDrag())
if (curPos != m_lastMousePos) {
TMouseEvent mouseEvent;
initToonzEvent(mouseEvent, e, height(), m_pressure, getDevPixRatio());
initToonzEvent(mouseEvent, e, height(), m_pressure, getDevPixRatio(),
m_isBusyOnTabletMove);
if (!m_isBusyOnTabletMove) {
m_isBusyOnTabletMove = true;
QTimer::singleShot(20, this, SLOT(releaseBusyOnTabletMove()));
}
#else
// It seems that the tabletEvent is called more often than mouseMoveEvent.
// So I fire the interval timer in order to limit the following process