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,6 +480,9 @@ void DragSelectionTool::FreeDeform::leftButtonDrag(const TPointD &pos,
const TMouseEvent &e) {
SelectionTool *tool = m_deformTool->getTool();
TPointD delta = pos - m_deformTool->getCurPos();
double pixelSize = tool->getPixelSize();
bool isFastDragging = norm2(delta) > 9.0 * pixelSize * pixelSize;
TPointD center = tool->getCenter();
int index = tool->getSelectedPoint();
FourPoints bbox = tool->getBBox();
@ -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());
}
//=============================================================================
@ -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
//-----------------------------------------------------------------------------

View file

@ -152,10 +152,13 @@ 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;
@ -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

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);
@ -105,6 +106,7 @@ void initToonzEvent(TMouseEvent &toonzEvent, QTabletEvent *event,
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