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 QPointF m_mousePos; // mouse position obtained with QMouseEvent::pos() or
// QTabletEvent::pos() // QTabletEvent::pos()
bool m_isTablet; bool m_isTablet;
bool m_isHighFrequent;
public: public:
TMouseEvent() TMouseEvent()
@ -104,7 +105,8 @@ public:
, m_modifiersMask(NO_KEY) , m_modifiersMask(NO_KEY)
, m_buttons(Qt::NoButton) , m_buttons(Qt::NoButton)
, m_button(Qt::NoButton) , m_button(Qt::NoButton)
, m_isTablet(false) {} , m_isTablet(false)
, m_isHighFrequent(false) {}
bool isShiftPressed() const { return (m_modifiersMask & SHIFT_KEY); } bool isShiftPressed() const { return (m_modifiersMask & SHIFT_KEY); }
bool isAltPressed() const { return (m_modifiersMask & ALT_KEY); } bool isAltPressed() const { return (m_modifiersMask & ALT_KEY); }
@ -115,6 +117,7 @@ public:
Qt::MouseButton button() const { return m_button; } Qt::MouseButton button() const { return m_button; }
QPointF mousePos() const { return m_mousePos; } QPointF mousePos() const { return m_mousePos; }
bool isTablet() const { return m_isTablet; } bool isTablet() const { return m_isTablet; }
bool isHighFrequent() const { return m_isHighFrequent; }
void setModifiers(bool shiftPressed, bool altPressed, bool ctrlPressed) { void setModifiers(bool shiftPressed, bool altPressed, bool ctrlPressed) {
m_modifiersMask = ModifierMask((shiftPressed << SHIFT_BITSHIFT) | 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(); RasterSelectionTool *tool = (RasterSelectionTool *)getTool();
tool->setNewFreeDeformer(); tool->setNewFreeDeformer();
if (!m_deformUndo) m_deformUndo = new UndoRasterDeform(tool); if (!m_deformUndo) m_deformUndo = new UndoRasterDeform(tool);
@ -257,7 +258,8 @@ void DragSelectionTool::RasterDeformTool::applyTransform(FourPoints bbox) {
RasterFreeDeformer *freeDeformer = RasterFreeDeformer *freeDeformer =
(RasterFreeDeformer *)tool->getFreeDeformer(); (RasterFreeDeformer *)tool->getFreeDeformer();
if (!freeDeformer) return; if (!freeDeformer) return;
freeDeformer->setNoAntialiasing(tool->getNoAntialiasingValue()); freeDeformer->setNoAntialiasing(tool->getNoAntialiasingValue() |
onFastDragging);
freeDeformer->setPoints(realBbox.getP00(), realBbox.getP10(), freeDeformer->setPoints(realBbox.getP00(), realBbox.getP10(),
realBbox.getP11(), realBbox.getP01()); realBbox.getP11(), realBbox.getP01());
freeDeformer->deformImage(); freeDeformer->deformImage();
@ -361,6 +363,14 @@ void DragSelectionTool::RasterFreeDeformTool::leftButtonDrag(
m_freeDeform->leftButtonDrag(pos, e); m_freeDeform->leftButtonDrag(pos, e);
} }
//-----------------------------------------------------------------------------
void DragSelectionTool::RasterFreeDeformTool::leftButtonUp(
const TPointD &pos, const TMouseEvent &e) {
m_freeDeform->leftButtonUp();
RasterDeformTool::leftButtonUp(pos, e);
}
//============================================================================= //=============================================================================
// RasterMoveSelectionTool // RasterMoveSelectionTool
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -404,8 +414,8 @@ DragSelectionTool::RasterScaleTool::RasterScaleTool(RasterSelectionTool *tool,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
TPointD DragSelectionTool::RasterScaleTool::transform(int index, TPointD DragSelectionTool::RasterScaleTool::transform(int index, TPointD newPos,
TPointD newPos) { bool onFastDragging) {
SelectionTool *tool = getTool(); SelectionTool *tool = getTool();
TPointD scaleValue = tool->m_deformValues.m_scaleValue; TPointD scaleValue = tool->m_deformValues.m_scaleValue;
@ -419,7 +429,7 @@ TPointD DragSelectionTool::RasterScaleTool::transform(int index,
if (!m_scale->scaleInCenter()) if (!m_scale->scaleInCenter())
tool->setCenter(m_scale->getNewCenter(index, startBboxs[0], scaleValue)); tool->setCenter(m_scale->getNewCenter(index, startBboxs[0], scaleValue));
applyTransform(bbox); applyTransform(bbox, onFastDragging);
tool->setBBox(bbox); tool->setBBox(bbox);
@ -441,6 +451,14 @@ void DragSelectionTool::RasterScaleTool::leftButtonDrag(const TPointD &pos,
m_scale->leftButtonDrag(pos, e); 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 ModifySavebox("ModifySavebox", 0);
TEnv::IntVar NoAntialiasing("NoAntialiasing", 0); TEnv::IntVar NoAntialiasing("NoAntialiasing", 0);
@ -605,9 +623,13 @@ void RasterSelectionTool::leftButtonDrag(const TPointD &pos,
invalidate(); invalidate();
return; 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); m_dragTool->leftButtonDrag(pos, e);
invalidate(); invalidate();
return; return;
@ -646,7 +668,6 @@ void RasterSelectionTool::leftButtonDrag(const TPointD &pos,
return; return;
} }
double pixelSize = getPixelSize();
TTool::Application *app = TTool::getApplication(); TTool::Application *app = TTool::getApplication();
if (!app || m_justSelected || !m_selecting || if (!app || m_justSelected || !m_selecting ||
tdistance2(pos, m_curPos) < 9.0 * pixelSize * pixelSize) tdistance2(pos, m_curPos) < 9.0 * pixelSize * pixelSize)

View file

@ -108,7 +108,7 @@ protected:
//! It's true when use RasterFreeDeformer //! It's true when use RasterFreeDeformer
bool m_isFreeDeformer; bool m_isFreeDeformer;
void applyTransform(FourPoints bbox) override; void applyTransform(FourPoints bbox, bool onFastDragging = false) override;
void applyTransform(TAffine aff, bool modifyCenter); void applyTransform(TAffine aff, bool modifyCenter);
void addTransformUndo() override; void addTransformUndo() override;
@ -143,6 +143,7 @@ class RasterFreeDeformTool final : public RasterDeformTool {
public: public:
RasterFreeDeformTool(RasterSelectionTool *tool); RasterFreeDeformTool(RasterSelectionTool *tool);
void leftButtonDrag(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;
}; };
//============================================================================= //=============================================================================
@ -169,9 +170,11 @@ class RasterScaleTool final : public RasterDeformTool {
public: public:
RasterScaleTool(RasterSelectionTool *tool, ScaleType type); RasterScaleTool(RasterSelectionTool *tool, ScaleType type);
/*! Return scale value. */ /*! 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 leftButtonDown(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonDrag(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 } // 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); VectorSelectionTool *vst = dynamic_cast<VectorSelectionTool *>(st);
RasterSelectionTool *rst = dynamic_cast<RasterSelectionTool *>(st); RasterSelectionTool *rst = dynamic_cast<RasterSelectionTool *>(st);
if (vst) if (vst)
@ -33,7 +35,8 @@ template <typename Tv, typename Tr, typename... Args> DragSelectionTool::DragToo
} }
DragSelectionTool::DragTool *createNewMoveSelectionTool(SelectionTool *st) { DragSelectionTool::DragTool *createNewMoveSelectionTool(SelectionTool *st) {
return createNewDragTool<VectorMoveSelectionTool, RasterMoveSelectionTool>(st); return createNewDragTool<VectorMoveSelectionTool, RasterMoveSelectionTool>(
st);
} }
DragSelectionTool::DragTool *createNewRotationTool(SelectionTool *st) { DragSelectionTool::DragTool *createNewRotationTool(SelectionTool *st) {
@ -44,7 +47,8 @@ DragSelectionTool::DragTool *createNewFreeDeformTool(SelectionTool *st) {
return createNewDragTool<VectorFreeDeformTool, RasterFreeDeformTool>(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); return createNewDragTool<VectorScaleTool, RasterScaleTool>(st, type);
} }
@ -476,6 +480,9 @@ void DragSelectionTool::FreeDeform::leftButtonDrag(const TPointD &pos,
const TMouseEvent &e) { const TMouseEvent &e) {
SelectionTool *tool = m_deformTool->getTool(); SelectionTool *tool = m_deformTool->getTool();
TPointD delta = pos - m_deformTool->getCurPos(); TPointD delta = pos - m_deformTool->getCurPos();
double pixelSize = tool->getPixelSize();
bool isFastDragging = norm2(delta) > 9.0 * pixelSize * pixelSize;
TPointD center = tool->getCenter(); TPointD center = tool->getCenter();
int index = tool->getSelectedPoint(); int index = tool->getSelectedPoint();
FourPoints bbox = tool->getBBox(); FourPoints bbox = tool->getBBox();
@ -491,7 +498,13 @@ void DragSelectionTool::FreeDeform::leftButtonDrag(const TPointD &pos,
} }
tool->setBBox(bbox); tool->setBBox(bbox);
m_deformTool->setCurPos(pos); 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; newPos = point + delta;
} }
m_scaleInCenter = m_isAltPressed; m_scaleInCenter = m_isAltPressed;
double pixelSize = tool->getPixelSize();
bool isFastDragging =
tdistance2(pos, m_deformTool->getCurPos()) > 9.0 * pixelSize * pixelSize;
m_deformTool->setCurPos(pos); 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; tool->m_deformValues.m_scaleValue = scaleValue;
TTool::getApplication()->getCurrentTool()->notifyToolChanged(); 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 // SelectionTool
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -152,10 +152,13 @@ public:
SelectionTool *getTool() const { return m_tool; } SelectionTool *getTool() const { return m_tool; }
virtual void transform(TAffine aff, double angle){} virtual void transform(TAffine aff, double angle) {}
virtual void transform(TAffine aff){} virtual void transform(TAffine aff) {}
virtual TPointD transform(int index, TPointD newPos) { return TPointD(); } virtual TPointD transform(int index, TPointD newPos,
virtual void addTransformUndo(){} bool onFastDragging = false) {
return TPointD();
}
virtual void addTransformUndo() {}
virtual void leftButtonDown(const TPointD &pos, const TMouseEvent &) = 0; virtual void leftButtonDown(const TPointD &pos, const TMouseEvent &) = 0;
virtual void leftButtonDrag(const TPointD &pos, const TMouseEvent &) = 0; virtual void leftButtonDrag(const TPointD &pos, const TMouseEvent &) = 0;
@ -177,7 +180,7 @@ protected:
public: public:
DeformTool(SelectionTool *tool); DeformTool(SelectionTool *tool);
virtual void applyTransform(FourPoints bbox) = 0; virtual void applyTransform(FourPoints bbox, bool onFastDragging = false) = 0;
virtual void applyTransform(TAffine aff){}; virtual void applyTransform(TAffine aff){};
void addTransformUndo() override = 0; void addTransformUndo() override = 0;
@ -234,6 +237,7 @@ class FreeDeform {
public: public:
FreeDeform(DeformTool *deformTool); FreeDeform(DeformTool *deformTool);
void leftButtonDrag(const TPointD &pos, const TMouseEvent &e); void leftButtonDrag(const TPointD &pos, const TMouseEvent &e);
void leftButtonUp();
}; };
//============================================================================= //=============================================================================
@ -254,11 +258,7 @@ public:
// Scale // Scale
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
enum class ScaleType { enum class ScaleType { GLOBAL = 0, HORIZONTAL, VERTICAL };
GLOBAL = 0,
HORIZONTAL,
VERTICAL
};
class Scale { class Scale {
TPointD m_startCenter; TPointD m_startCenter;
@ -270,7 +270,6 @@ class Scale {
DeformTool *m_deformTool; DeformTool *m_deformTool;
public: public:
ScaleType m_type; ScaleType m_type;
Scale(DeformTool *deformTool, ScaleType type); Scale(DeformTool *deformTool, ScaleType type);
@ -301,12 +300,13 @@ compute scaleValue. */
void leftButtonDown(const TPointD &pos, const TMouseEvent &e); void leftButtonDown(const TPointD &pos, const TMouseEvent &e);
void leftButtonDrag(const TPointD &pos, const TMouseEvent &e); void leftButtonDrag(const TPointD &pos, const TMouseEvent &e);
void leftButtonUp();
std::vector<FourPoints> getStartBboxs() const { return m_startBboxs; } std::vector<FourPoints> getStartBboxs() const { return m_startBboxs; }
TPointD getStartCenter() const { return m_startCenter; } TPointD getStartCenter() const { return m_startCenter; }
bool scaleInCenter() const { return m_scaleInCenter; } bool scaleInCenter() const { return m_scaleInCenter; }
}; };
}; }; // namespace DragSelectionTool
//============================================================================= //=============================================================================
// Utility // Utility
@ -315,7 +315,8 @@ compute scaleValue. */
DragSelectionTool::DragTool *createNewMoveSelectionTool(SelectionTool *st); DragSelectionTool::DragTool *createNewMoveSelectionTool(SelectionTool *st);
DragSelectionTool::DragTool *createNewRotationTool(SelectionTool *st); DragSelectionTool::DragTool *createNewRotationTool(SelectionTool *st);
DragSelectionTool::DragTool *createNewFreeDeformTool(SelectionTool *st); DragSelectionTool::DragTool *createNewFreeDeformTool(SelectionTool *st);
DragSelectionTool::DragTool *createNewScaleTool(SelectionTool *st, DragSelectionTool::ScaleType type); DragSelectionTool::DragTool *createNewScaleTool(
SelectionTool *st, DragSelectionTool::ScaleType type);
//============================================================================= //=============================================================================
// SelectionTool // 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(); SelectionTool *tool = getTool();
std::unique_ptr<VFDScopedBlock> localVfdScopedBlock; std::unique_ptr<VFDScopedBlock> localVfdScopedBlock;
@ -852,8 +853,8 @@ DragSelectionTool::VectorScaleTool::VectorScaleTool(VectorSelectionTool *tool,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
TPointD DragSelectionTool::VectorScaleTool::transform(int index, TPointD DragSelectionTool::VectorScaleTool::transform(int index, TPointD newPos,
TPointD newPos) { bool onFastDragging) {
SelectionTool *tool = getTool(); SelectionTool *tool = getTool();
TPointD scaleValue = tool->m_deformValues.m_scaleValue; TPointD scaleValue = tool->m_deformValues.m_scaleValue;

View file

@ -150,7 +150,7 @@ public:
VectorDeformTool(VectorSelectionTool *tool); VectorDeformTool(VectorSelectionTool *tool);
~VectorDeformTool(); ~VectorDeformTool();
void applyTransform(FourPoints bbox) override; void applyTransform(FourPoints bbox, bool onFastDragging = false) override;
void addTransformUndo() override; void addTransformUndo() override;
/*! Transform whole level and add undo. */ /*! Transform whole level and add undo. */
@ -225,8 +225,8 @@ class VectorScaleTool final : public VectorDeformTool {
public: public:
VectorScaleTool(VectorSelectionTool *tool, ScaleType type); VectorScaleTool(VectorSelectionTool *tool, ScaleType type);
TPointD transform(int index, TPointD transform(int index, TPointD newPos, bool onFastDragging = false)
TPointD newPos) override; //!< Returns scale value. override; //!< Returns scale value.
void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override; void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonDrag(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, 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( toonzEvent.m_pos = TPointD(
event->posF().x() * (float)devPixRatio, event->posF().x() * (float)devPixRatio,
(float)widgetHeight - 1.0f - event->posF().y() * (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_buttons = event->buttons();
toonzEvent.m_button = event->button(); toonzEvent.m_button = event->button();
toonzEvent.m_isTablet = true; toonzEvent.m_isTablet = true;
toonzEvent.m_isHighFrequent = isHighFrequent;
// this delays autosave during stylus button press until after the next // this delays autosave during stylus button press until after the next
// brush stroke - this minimizes problems from interruptions to tablet input // brush stroke - this minimizes problems from interruptions to tablet input
TApp::instance()->getCurrentTool()->setToolBusy(true); 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) #if defined(_WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
// Use the application attribute Qt::AA_CompressTabletEvents instead of the // Use the application attribute Qt::AA_CompressTabletEvents instead of the
// delay timer // 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) { if (curPos != m_lastMousePos) {
TMouseEvent mouseEvent; 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 #else
// It seems that the tabletEvent is called more often than mouseMoveEvent. // It seems that the tabletEvent is called more often than mouseMoveEvent.
// So I fire the interval timer in order to limit the following process // So I fire the interval timer in order to limit the following process