Commit 411a7016 authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

[FEATURE] Implemented "Delayed Stroke" feature for brush smoothing

This patch adds two improvements to the Stabilizer algorithm implemented
by Juan Luis Boya García:

1) "Delayed Stroke" feature. If enabled the brush has a dead zone, where
   nothing is painted. This is extremely handy when one needs to paint
   a smooth line with explicit angles.

2) "Finish line" option for the brush stanilizer. When option is disabled,
   the line will not jump to the cursor position in the end of the stroke.

CCMAIL:kimageshop@kde.org
parent 52d20e81
......@@ -321,6 +321,12 @@ QDebug operator<<(QDebug dbg, const KisPaintInformation &info)
return dbg.space();
}
KisPaintInformation KisPaintInformation::mix(qreal t, const KisPaintInformation& pi1, const KisPaintInformation& pi2)
{
QPointF pt = (1 - t) * pi1.pos() + t * pi2.pos();
return mix(pt, t, pi1, pi2);
}
KisPaintInformation KisPaintInformation::mix(const QPointF& p, qreal t, const KisPaintInformation& pi1, const KisPaintInformation& pi2)
{
qreal pressure = (1 - t) * pi1.pressure() + t * pi2.pressure();
......
......@@ -184,6 +184,7 @@ public:
/// (1-t) * p1 + t * p2
static KisPaintInformation mix(const QPointF& p, qreal t, const KisPaintInformation& p1, const KisPaintInformation& p2);
static KisPaintInformation mix(qreal t, const KisPaintInformation& pi1, const KisPaintInformation& pi2);
static qreal tiltDirection(const KisPaintInformation& info, bool normalize=true);
static qreal tiltElevation(const KisPaintInformation& info, qreal maxTiltX=60.0, qreal maxTiltY=60.0, bool normalize=true);
......
......@@ -48,74 +48,82 @@ KisToolBrush::~KisToolBrush()
int KisToolBrush::smoothingType() const
{
return m_smoothingOptions.smoothingType();
return smoothingOptions()->smoothingType();
}
bool KisToolBrush::smoothPressure() const
{
return m_smoothingOptions.smoothPressure();
return smoothingOptions()->smoothPressure();
}
int KisToolBrush::smoothnessQuality() const
{
return m_smoothingOptions.smoothnessDistance();
return smoothingOptions()->smoothnessDistance();
}
qreal KisToolBrush::smoothnessFactor() const
{
return m_smoothingOptions.tailAggressiveness();
return smoothingOptions()->tailAggressiveness();
}
void KisToolBrush::slotSetSmoothingType(int index)
{
switch (index) {
case 0:
m_smoothingOptions.setSmoothingType(KisSmoothingOptions::NO_SMOOTHING);
m_sliderSmoothnessDistance->setEnabled(false);
m_sliderTailAggressiveness->setEnabled(false);
m_chkSmoothPressure->setEnabled(false);
m_chkUseScalableDistance->setEnabled(false);
smoothingOptions()->setSmoothingType(KisSmoothingOptions::NO_SMOOTHING);
showControl(m_sliderSmoothnessDistance, false);
showControl(m_sliderTailAggressiveness, false);
showControl(m_chkSmoothPressure, false);
showControl(m_chkUseScalableDistance, false);
showControl(m_sliderDelayDistance, false);
showControl(m_chkFinishStabilizedCurve, false);
break;
case 1:
m_smoothingOptions.setSmoothingType(KisSmoothingOptions::SIMPLE_SMOOTHING);
m_sliderSmoothnessDistance->setEnabled(false);
m_sliderTailAggressiveness->setEnabled(false);
m_chkSmoothPressure->setEnabled(false);
m_chkUseScalableDistance->setEnabled(false);
smoothingOptions()->setSmoothingType(KisSmoothingOptions::SIMPLE_SMOOTHING);
showControl(m_sliderSmoothnessDistance, false);
showControl(m_sliderTailAggressiveness, false);
showControl(m_chkSmoothPressure, false);
showControl(m_chkUseScalableDistance, false);
showControl(m_sliderDelayDistance, false);
showControl(m_chkFinishStabilizedCurve, false);
break;
case 2:
m_smoothingOptions.setSmoothingType(KisSmoothingOptions::WEIGHTED_SMOOTHING);
m_sliderSmoothnessDistance->setEnabled(true);
m_sliderTailAggressiveness->setEnabled(true);
m_chkSmoothPressure->setEnabled(true);
m_chkUseScalableDistance->setEnabled(true);
smoothingOptions()->setSmoothingType(KisSmoothingOptions::WEIGHTED_SMOOTHING);
showControl(m_sliderSmoothnessDistance, true);
showControl(m_sliderTailAggressiveness, true);
showControl(m_chkSmoothPressure, true);
showControl(m_chkUseScalableDistance, true);
showControl(m_sliderDelayDistance, false);
showControl(m_chkFinishStabilizedCurve, false);
break;
case 3:
default:
m_smoothingOptions.setSmoothingType(KisSmoothingOptions::STABILIZER);
m_sliderSmoothnessDistance->setEnabled(true);
m_sliderTailAggressiveness->setEnabled(false);
m_chkSmoothPressure->setEnabled(false);
m_chkUseScalableDistance->setEnabled(false);
smoothingOptions()->setSmoothingType(KisSmoothingOptions::STABILIZER);
showControl(m_sliderSmoothnessDistance, true);
showControl(m_sliderTailAggressiveness, false);
showControl(m_chkSmoothPressure, false);
showControl(m_chkUseScalableDistance, false);
showControl(m_sliderDelayDistance, true);
showControl(m_chkFinishStabilizedCurve, true);
}
emit smoothingTypeChanged();
}
void KisToolBrush::slotSetSmoothnessDistance(qreal distance)
{
m_smoothingOptions.setSmoothnessDistance(distance);
smoothingOptions()->setSmoothnessDistance(distance);
emit smoothnessQualityChanged();
}
void KisToolBrush::slotSetTailAgressiveness(qreal argh_rhhrr)
{
m_smoothingOptions.setTailAggressiveness(argh_rhhrr);
smoothingOptions()->setTailAggressiveness(argh_rhhrr);
emit smoothnessFactorChanged();
}
void KisToolBrush::setSmoothPressure(bool value)
{
m_smoothingOptions.setSmoothPressure(value);
smoothingOptions()->setSmoothPressure(value);
}
void KisToolBrush::slotSetMagnetism(int magnetism)
......@@ -125,7 +133,13 @@ void KisToolBrush::slotSetMagnetism(int magnetism)
bool KisToolBrush::useScalableDistance() const
{
return m_smoothingOptions.useScalableDistance();
return smoothingOptions()->useScalableDistance();
}
void KisToolBrush::setUseScalableDistance(bool value)
{
smoothingOptions()->setUseScalableDistance(value);
emit useScalableDistanceChanged();
}
void KisToolBrush::resetCursorStyle()
......@@ -136,7 +150,7 @@ void KisToolBrush::resetCursorStyle()
// When the stabilizer is in use, we avoid using the brush outline cursor,
// because it would hide the real position of the cursor to the user,
// yielding unexpected results.
if (m_smoothingOptions.smoothingType() == KisSmoothingOptions::STABILIZER
if (smoothingOptions()->smoothingType() == KisSmoothingOptions::STABILIZER
&& cursorStyle == CURSOR_STYLE_OUTLINE) {
useCursor(KisCursor::roundCursor());
} else {
......@@ -144,10 +158,38 @@ void KisToolBrush::resetCursorStyle()
}
}
void KisToolBrush::setUseScalableDistance(bool value)
bool KisToolBrush::useDelayDistance() const
{
m_smoothingOptions.setUseScalableDistance(value);
emit useScalableDistanceChanged();
return smoothingOptions()->useDelayDistance();
}
qreal KisToolBrush::delayDistance() const
{
return smoothingOptions()->delayDistance();
}
void KisToolBrush::setUseDelayDistance(bool value)
{
smoothingOptions()->setUseDelayDistance(value);
enableControl(m_chkFinishStabilizedCurve, !value);
emit useDelayDistanceChanged();
}
void KisToolBrush::setDelayDistance(qreal value)
{
smoothingOptions()->setDelayDistance(value);
emit delayDistanceChanged();
}
void KisToolBrush::setFinishStabilizedCurve(bool value)
{
smoothingOptions()->setFinishStabilizedCurve(value);
emit finishStabilizedCurveChanged();
}
bool KisToolBrush::finishStabilizedCurve() const
{
return smoothingOptions()->finishStabilizedCurve();
}
QWidget * KisToolBrush::createOptionWidget()
......@@ -175,28 +217,52 @@ QWidget * KisToolBrush::createOptionWidget()
m_sliderSmoothnessDistance->setRange(3.0, MAXIMUM_SMOOTHNESS_DISTANCE, 1);
m_sliderSmoothnessDistance->setEnabled(true);
connect(m_sliderSmoothnessDistance, SIGNAL(valueChanged(qreal)), SLOT(slotSetSmoothnessDistance(qreal)));
m_sliderSmoothnessDistance->setValue(m_smoothingOptions.smoothnessDistance());
m_sliderSmoothnessDistance->setValue(smoothingOptions()->smoothnessDistance());
addOptionWidgetOption(m_sliderSmoothnessDistance, new QLabel(i18n("Distance:")));
// Finish stabilizer curve
m_chkFinishStabilizedCurve = new QCheckBox("", optionsWidget);
connect(m_chkFinishStabilizedCurve, SIGNAL(toggled(bool)), this, SLOT(setFinishStabilizedCurve(bool)));
m_chkFinishStabilizedCurve->setChecked(smoothingOptions()->finishStabilizedCurve());
// Delay Distance for Stabilizer
m_chkDelayDistance = new QCheckBox(i18n("Delay:"), optionsWidget);
m_chkDelayDistance->setToolTip(i18n("Delay the brush stroke to make the line smoother"));
m_chkDelayDistance->setLayoutDirection(Qt::RightToLeft);
connect(m_chkDelayDistance, SIGNAL(toggled(bool)), this, SLOT(setUseDelayDistance(bool)));
m_sliderDelayDistance = new KisDoubleSliderSpinBox(optionsWidget);
m_sliderDelayDistance->setToolTip(i18n("Radius where the brush is blocked"));
m_sliderDelayDistance->setRange(0, 500);
m_sliderDelayDistance->setSuffix(i18n(" px"));
connect(m_chkDelayDistance, SIGNAL(toggled(bool)), m_sliderDelayDistance, SLOT(setEnabled(bool)));
connect(m_sliderDelayDistance, SIGNAL(valueChanged(qreal)), SLOT(setDelayDistance(qreal)));
addOptionWidgetOption(m_sliderDelayDistance, m_chkDelayDistance);
addOptionWidgetOption(m_chkFinishStabilizedCurve, new QLabel(i18n("Finish line:")));
m_chkDelayDistance->setChecked(smoothingOptions()->useDelayDistance());
m_sliderDelayDistance->setValue(smoothingOptions()->delayDistance());
m_sliderTailAggressiveness = new KisDoubleSliderSpinBox(optionsWidget);
m_sliderTailAggressiveness->setRange(0.0, 1.0, 2);
m_sliderTailAggressiveness->setEnabled(true);
connect(m_sliderTailAggressiveness, SIGNAL(valueChanged(qreal)), SLOT(slotSetTailAgressiveness(qreal)));
m_sliderTailAggressiveness->setValue(m_smoothingOptions.tailAggressiveness());
m_sliderTailAggressiveness->setValue(smoothingOptions()->tailAggressiveness());
addOptionWidgetOption(m_sliderTailAggressiveness, new QLabel(i18n("Stroke Ending:")));
m_chkSmoothPressure = new QCheckBox("", optionsWidget);
m_chkSmoothPressure->setChecked(m_smoothingOptions.smoothPressure());
m_chkSmoothPressure->setChecked(smoothingOptions()->smoothPressure());
connect(m_chkSmoothPressure, SIGNAL(toggled(bool)), this, SLOT(setSmoothPressure(bool)));
addOptionWidgetOption(m_chkSmoothPressure, new QLabel(i18n("Smooth Pressure")));
m_chkUseScalableDistance = new QCheckBox("", optionsWidget);
m_chkUseScalableDistance->setChecked(m_smoothingOptions.useScalableDistance());
m_chkUseScalableDistance->setChecked(smoothingOptions()->useScalableDistance());
connect(m_chkUseScalableDistance, SIGNAL(toggled(bool)), this, SLOT(setUseScalableDistance(bool)));
addOptionWidgetOption(m_chkUseScalableDistance, new QLabel(i18n("Scalable Distance")));
slotSetSmoothingType((int)m_smoothingOptions.smoothingType());
m_cmbSmoothingType->setCurrentIndex((int)m_smoothingOptions.smoothingType());
slotSetSmoothingType((int)smoothingOptions()->smoothingType());
m_cmbSmoothingType->setCurrentIndex((int)smoothingOptions()->smoothingType());
// Drawing assistant configuration
m_chkAssistant = new QCheckBox(i18n("Assistant:"), optionsWidget);
......
......@@ -43,6 +43,12 @@ class KisToolBrush : public KisToolFreehand
Q_PROPERTY(int smoothingType READ smoothingType WRITE slotSetSmoothingType NOTIFY smoothingTypeChanged)
Q_PROPERTY(bool useScalableDistance READ useScalableDistance WRITE setUseScalableDistance NOTIFY useScalableDistanceChanged)
Q_PROPERTY(bool useDelayDistance READ useDelayDistance WRITE setUseDelayDistance NOTIFY useDelayDistanceChanged)
Q_PROPERTY(bool delayDistance READ delayDistance WRITE setDelayDistance NOTIFY delayDistanceChanged)
Q_PROPERTY(bool finishStabilizedCurve READ finishStabilizedCurve WRITE setFinishStabilizedCurve NOTIFY finishStabilizedCurveChanged)
public:
KisToolBrush(KoCanvasBase * canvas);
virtual ~KisToolBrush();
......@@ -55,6 +61,11 @@ public:
int smoothingType() const;
bool useScalableDistance() const;
bool useDelayDistance() const;
qreal delayDistance() const;
bool finishStabilizedCurve() const;
protected slots:
virtual void resetCursorStyle();
......@@ -66,6 +77,11 @@ public slots:
void setSmoothPressure(bool value);
void setUseScalableDistance(bool value);
void setUseDelayDistance(bool value);
void setDelayDistance(qreal value);
void setFinishStabilizedCurve(bool value);
Q_SIGNALS:
void smoothnessQualityChanged();
void smoothnessFactorChanged();
......@@ -73,6 +89,10 @@ Q_SIGNALS:
void smoothingTypeChanged();
void useScalableDistanceChanged();
void useDelayDistanceChanged();
void delayDistanceChanged();
void finishStabilizedCurveChanged();
private:
QGridLayout *m_optionLayout;
QComboBox *m_cmbSmoothingType;
......@@ -83,6 +103,11 @@ private:
KisDoubleSliderSpinBox *m_sliderTailAggressiveness;
QCheckBox *m_chkSmoothPressure;
QCheckBox *m_chkUseScalableDistance;
QCheckBox *m_chkDelayDistance;
KisDoubleSliderSpinBox *m_sliderDelayDistance;
QCheckBox *m_chkFinishStabilizedCurve;
};
......
......@@ -1145,6 +1145,36 @@ void KisConfig::setLineSmoothingScalableDistance(bool value)
m_cfg.writeEntry("LineSmoothingScalableDistance", value);
}
qreal KisConfig::lineSmoothingDelayDistance() const
{
return m_cfg.readEntry("LineSmoothingDelayDistance", 50.0);
}
void KisConfig::setLineSmoothingDelayDistance(qreal value)
{
m_cfg.writeEntry("LineSmoothingDelayDistance", value);
}
bool KisConfig::lineSmoothingUseDelayDistance() const
{
return m_cfg.readEntry("LineSmoothingUseDelayDistance", true);
}
void KisConfig::setLineSmoothingUseDelayDistance(bool value)
{
m_cfg.writeEntry("LineSmoothingUseDelayDistance", value);
}
bool KisConfig::lineSmoothingFinishStabilizedCurve() const
{
return m_cfg.readEntry("LineSmoothingFinishStabilizedCurve", true);
}
void KisConfig::setLineSmoothingFinishStabilizedCurve(bool value)
{
m_cfg.writeEntry("LineSmoothingFinishStabilizedCurve", value);
}
int KisConfig::paletteDockerPaletteViewSectionSize() const
{
return m_cfg.readEntry("paletteDockerPaletteViewSectionSize", 12);
......
......@@ -348,6 +348,15 @@ public:
bool lineSmoothingScalableDistance() const;
void setLineSmoothingScalableDistance(bool value);
qreal lineSmoothingDelayDistance() const;
void setLineSmoothingDelayDistance(qreal value);
bool lineSmoothingUseDelayDistance() const;
void setLineSmoothingUseDelayDistance(bool value);
bool lineSmoothingFinishStabilizedCurve() const;
void setLineSmoothingFinishStabilizedCurve(bool value);
int paletteDockerPaletteViewSectionSize() const;
void setPaletteDockerPaletteViewSectionSize(int value) const;
......
......@@ -20,11 +20,6 @@
#include "kis_config.h"
KisSmoothingOptions::KisSmoothingOptions()
: m_smoothingType(WEIGHTED_SMOOTHING)
, m_smoothnessDistance(55.0)
, m_tailAggressiveness(0.15)
, m_smoothPressure(false)
, m_useScalableDistance(true)
{
KisConfig cfg;
m_smoothingType = (SmoothingType)cfg.lineSmoothingType();
......@@ -32,6 +27,9 @@ KisSmoothingOptions::KisSmoothingOptions()
m_tailAggressiveness = cfg.lineSmoothingTailAggressiveness();
m_smoothPressure = cfg.lineSmoothingSmoothPressure();
m_useScalableDistance = cfg.lineSmoothingScalableDistance();
m_delayDistance = cfg.lineSmoothingDelayDistance();
m_useDelayDistance = cfg.lineSmoothingUseDelayDistance();
m_finishStabilizedCurve = cfg.lineSmoothingFinishStabilizedCurve();
}
KisSmoothingOptions::SmoothingType KisSmoothingOptions::smoothingType() const
......@@ -93,3 +91,39 @@ void KisSmoothingOptions::setUseScalableDistance(bool value)
cfg.setLineSmoothingScalableDistance(value);
m_useScalableDistance = value;
}
qreal KisSmoothingOptions::delayDistance() const
{
return m_delayDistance;
}
void KisSmoothingOptions::setDelayDistance(qreal value)
{
KisConfig cfg;
cfg.setLineSmoothingDelayDistance(value);
m_delayDistance = value;
}
bool KisSmoothingOptions::useDelayDistance() const
{
return m_useDelayDistance;
}
void KisSmoothingOptions::setUseDelayDistance(bool value)
{
KisConfig cfg;
cfg.setLineSmoothingUseDelayDistance(value);
m_useDelayDistance = value;
}
void KisSmoothingOptions::setFinishStabilizedCurve(bool value)
{
KisConfig cfg;
cfg.setLineSmoothingFinishStabilizedCurve(value);
m_finishStabilizedCurve = value;
}
bool KisSmoothingOptions::finishStabilizedCurve() const
{
return m_finishStabilizedCurve;
}
......@@ -19,8 +19,11 @@
#define KIS_SMOOTHING_OPTIONS_H
#include <qglobal.h>
#include <QSharedPointer>
#include <krita_export.h>
class KRITAUI_EXPORT KisSmoothingOptions
{
public:
......@@ -50,12 +53,26 @@ public:
bool useScalableDistance() const;
void setUseScalableDistance(bool value);
qreal delayDistance() const;
void setDelayDistance(qreal value);
void setUseDelayDistance(bool value);
bool useDelayDistance() const;
void setFinishStabilizedCurve(bool value);
bool finishStabilizedCurve() const;
private:
SmoothingType m_smoothingType;
qreal m_smoothnessDistance;
qreal m_tailAggressiveness;
bool m_smoothPressure;
bool m_useScalableDistance;
qreal m_delayDistance;
bool m_useDelayDistance;
bool m_finishStabilizedCurve;
};
typedef QSharedPointer<KisSmoothingOptions> KisSmoothingOptionsSP;
#endif // KIS_SMOOTHING_OPTIONS_H
......@@ -71,6 +71,9 @@ KisToolFreehand::KisToolFreehand(KoCanvasBase * canvas, const QCursor & cursor,
m_infoBuilder = new KisToolPaintingInformationBuilder(this);
m_recordingAdapter = new KisRecordingAdapter();
m_helper = new KisToolFreehandHelper(m_infoBuilder, transactionText, m_recordingAdapter);
connect(m_helper, SIGNAL(requestExplicitUpdateOutline()),
SLOT(explicitUpdateOutline()));
}
KisToolFreehand::~KisToolFreehand()
......@@ -80,6 +83,11 @@ KisToolFreehand::~KisToolFreehand()
delete m_infoBuilder;
}
KisSmoothingOptionsSP KisToolFreehand::smoothingOptions() const
{
return m_helper->smoothingOptions();
}
void KisToolFreehand::resetCursorStyle()
{
KisConfig cfg;
......@@ -155,7 +163,6 @@ void KisToolFreehand::initStroke(KoPointerEvent *event)
{
setCurrentNodeLocked(true);
m_helper->setSmoothness(m_smoothingOptions);
m_helper->initPaint(event, canvas()->resourceManager(),
image(),
image().data(),
......@@ -370,6 +377,11 @@ qreal KisToolFreehand::calculatePerspective(const QPointF &documentPoint)
return perspective;
}
void KisToolFreehand::explicitUpdateOutline()
{
requestUpdateOutline(m_outlineDocPoint, 0);
}
QPainterPath KisToolFreehand::getOutlinePath(const QPointF &documentPos,
const KoPointerEvent *event,
KisPaintOpSettings::OutlineMode outlineMode)
......
......@@ -88,6 +88,7 @@ protected:
protected slots:
void explicitUpdateOutline();
virtual void resetCursorStyle();
void setAssistant(bool assistant);
......@@ -108,7 +109,7 @@ private:
protected:
KisSmoothingOptions m_smoothingOptions;
KisSmoothingOptionsSP smoothingOptions() const;
bool m_assistant;
double m_magnetism;
......
......@@ -104,7 +104,7 @@ struct KisToolFreehandHelper::Private
KisPaintInformation previousPaintInformation;
KisPaintInformation olderPaintInformation;
KisSmoothingOptions smoothingOptions;
KisSmoothingOptionsSP smoothingOptions;
QTimer airbrushingTimer;
......@@ -117,6 +117,10 @@ struct KisToolFreehandHelper::Private
QQueue<KisPaintInformation> stabilizerDeque;
KisPaintInformation stabilizerLastPaintInfo;
QTimer stabilizerPollTimer;
static KisPaintInformation
getStabilizedPaintInfo(const QQueue<KisPaintInformation> &queue,
const KisPaintInformation &lastPaintInfo);
};
......@@ -127,14 +131,12 @@ KisToolFreehandHelper::KisToolFreehandHelper(KisPaintingInformationBuilder *info
{
m_d->infoBuilder = infoBuilder;
m_d->recordingAdapter = recordingAdapter;
m_d->transactionText = transactionText;
m_d->smoothingOptions = KisSmoothingOptionsSP(new KisSmoothingOptions());
m_d->strokeTimeoutTimer.setSingleShot(true);
connect(&m_d->strokeTimeoutTimer, SIGNAL(timeout()), SLOT(finishStroke()));
connect(&m_d->airbrushingTimer, SIGNAL(timeout()), SLOT(doAirbrushing()));
connect(&m_d->stabilizerPollTimer, SIGNAL(timeout()), SLOT(stabilizerPollAndPaint()));
}
......@@ -143,11 +145,16 @@ KisToolFreehandHelper::~KisToolFreehandHelper()
delete m_d;
}
void KisToolFreehandHelper::setSmoothness(const KisSmoothingOptions &smoothingOptions)
void KisToolFreehandHelper::setSmoothness(KisSmoothingOptionsSP smoothingOptions)
{
m_d->smoothingOptions = smoothingOptions;
}
KisSmoothingOptionsSP KisToolFreehandHelper::smoothingOptions() const
{
return m_d->smoothingOptions;
}
QPainterPath KisToolFreehandHelper::paintOpOutline(const QPointF &savedCursorPos,
const KoPointerEvent *event,
const KisPaintOpSettings *globalSettings,
......@@ -166,7 +173,21 @@ QPainterPath KisToolFreehandHelper::paintOpOutline(const QPointF &savedCursorPos
KisPaintInformation::DistanceInformationRegistrar registrar =
info.registerDistanceInformation(&distanceInfo);
return settings->brushOutline(info, mode);
QPainterPath outline = settings->brushOutline(info, mode);
if (m_d->resources &&
m_d->smoothingOptions->smoothingType() == KisSmoothingOptions::STABILIZER &&
m_d->smoothingOptions->useDelayDistance()) {