Commit f9cbf6a1 by Halla Rempt

### Implement line smoothing in Krita

```REVIEW:108049
BUG:281267```
parent 0260a759
 ... ... @@ -111,7 +111,7 @@ public: /// Number of ms since the beginning of the stroke int currentTime() const; void toXML(QDomDocument&, QDomElement&) const; static KisPaintInformation fromXML(const QDomElement&); ... ...
 ... ... @@ -24,9 +24,23 @@ * to be passed for the next call. */ struct KisDistanceInformation { KisDistanceInformation() : distance(0), spacing(0) {} KisDistanceInformation(double _distance, double _spacing) : distance(_distance), spacing(_spacing) {} void clear() { distance = 0; spacing = 0;} KisDistanceInformation() : distance(0) , spacing(0) {} KisDistanceInformation(double _distance, double _spacing) : distance(_distance) , spacing(_spacing) {} void clear() { distance = 0; spacing = 0; } double distance; double spacing; }; ... ...
 ... ... @@ -30,10 +30,12 @@ KisDynamicSensorSpeed::KisDynamicSensorSpeed() : KisDynamicSensor(SpeedId) } qreal KisDynamicSensorSpeed::value(const KisPaintInformation& info) { int dt = qMax(1, info.currentTime() - m_lastTime); // make sure dt > 1 int deltaTime = qMax(1, info.currentTime() - m_lastTime); // make sure deltaTime > 1 m_lastTime = info.currentTime(); double currentMove = info.movement().norm() / dt; m_speed = qMin(1.0, (m_speed * 0.9 + currentMove * 0.1)); // average it to get nicer result, at the price of being less mathematically correct, but we quicly reach a situation where dt = 1 and currentMove = 1 double currentMove = info.movement().norm() / deltaTime; // Average it to get nicer result, at the price of being less mathematically correct, // but we quickly reach a situation where dt = 1 and currentMove = 1 m_speed = qMin(1.0, (m_speed * 0.9 + currentMove * 0.1)); return m_speed; } ... ...
 ... ... @@ -21,19 +21,22 @@ #include "kis_tool_brush.h" #include #include #include #include "kis_cursor.h" #include "kis_slider_spin_box.h" #define MAXIMUM_SMOOTHNESS 1000 #define MAXIMUM_SMOOTHNESS_QUALITY 100 // 0..100 #define MAXIMUM_SMOOTHNESS_FACTOR 1000.0 // 0..1000.0 == weight in gui #define MAXIMUM_MAGNETISM 1000 KisToolBrush::KisToolBrush(KoCanvasBase * canvas) : KisToolFreehand(canvas, KisCursor::load("tool_freehand_cursor.png", 5, 5), i18nc("(qtundo-format)", "Brush")) : KisToolFreehand(canvas, KisCursor::load("tool_freehand_cursor.png", 5, 5), i18nc("(qtundo-format)", "Brush")) { setObjectName("tool_brush"); } ... ... @@ -42,9 +45,35 @@ KisToolBrush::~KisToolBrush() { } void KisToolBrush::slotSetSmoothness(int smoothness) void KisToolBrush::slotSetSmoothingType(int index) { m_smoothness = smoothness / (double)MAXIMUM_SMOOTHNESS; switch (index) { case 0: m_smoothingOptions.smoothingType = KisSmoothingOptions::NO_SMOOTHING; m_sliderSmoothnessFactor->setEnabled(false); m_sliderSmoothnessQuality->setEnabled(false); break; case 1: m_smoothingOptions.smoothingType = KisSmoothingOptions::SIMPLE_SMOOTHING; m_sliderSmoothnessFactor->setEnabled(false); m_sliderSmoothnessQuality->setEnabled(false); break; case 2: default: m_smoothingOptions.smoothingType = KisSmoothingOptions::WEIGHTED_SMOOTHING; m_sliderSmoothnessFactor->setEnabled(true); m_sliderSmoothnessQuality->setEnabled(true); } } void KisToolBrush::slotSetSmoothnessQuality(int quality) { m_smoothingOptions.smoothnessQuality = quality; } void KisToolBrush::slotSetSmoothnessFactor(qreal factor) { m_smoothingOptions.smoothnessFactor = factor; } void KisToolBrush::slotSetMagnetism(int magnetism) ... ... @@ -54,23 +83,30 @@ void KisToolBrush::slotSetMagnetism(int magnetism) QWidget * KisToolBrush::createOptionWidget() { QWidget * optionWidget = KisToolFreehand::createOptionWidget(); optionWidget->setObjectName(toolId() + "option widget"); m_chkSmooth = new QCheckBox(i18nc("smooth out the curves while drawing", "Smoothness:"), optionWidget); m_chkSmooth->setObjectName("chkSmooth"); m_chkSmooth->setChecked(m_smooth); connect(m_chkSmooth, SIGNAL(toggled(bool)), this, SLOT(setSmooth(bool))); // Line smoothing configuration m_cmbSmoothingType = new QComboBox(optionWidget); m_cmbSmoothingType->addItems(QStringList() << i18n("No Smoothing") << i18n("Basic Smoothing") << i18n("Weighted Smoothing")); m_cmbSmoothingType->setCurrentIndex(2); connect(m_cmbSmoothingType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetSmoothingType(int))); addOptionWidgetOption(m_cmbSmoothingType); m_sliderSmoothnessQuality = new KisSliderSpinBox(optionWidget); m_sliderSmoothnessQuality->setRange(1, MAXIMUM_SMOOTHNESS_QUALITY); m_sliderSmoothnessQuality->setEnabled(true); connect(m_sliderSmoothnessQuality, SIGNAL(valueChanged(int)), SLOT(slotSetSmoothnessQuality(int))); m_sliderSmoothnessQuality->setValue(m_smoothingOptions.smoothnessQuality); addOptionWidgetOption(m_sliderSmoothnessQuality, new QLabel(i18n("Quality:"))); m_sliderSmoothness = new KisSliderSpinBox(optionWidget); m_sliderSmoothness->setRange(0, MAXIMUM_SMOOTHNESS); m_sliderSmoothness->setEnabled(true); connect(m_chkSmooth, SIGNAL(toggled(bool)), m_sliderSmoothness, SLOT(setEnabled(bool))); connect(m_sliderSmoothness, SIGNAL(valueChanged(int)), SLOT(slotSetSmoothness(int))); m_sliderSmoothness->setValue(m_smoothness * MAXIMUM_SMOOTHNESS); m_sliderSmoothnessFactor = new KisDoubleSliderSpinBox(optionWidget); m_sliderSmoothnessFactor->setRange(3.0, MAXIMUM_SMOOTHNESS_FACTOR, 1); m_sliderSmoothnessFactor->setEnabled(true); connect(m_sliderSmoothnessFactor, SIGNAL(valueChanged(qreal)), SLOT(slotSetSmoothnessFactor(qreal))); m_sliderSmoothnessFactor->setValue(m_smoothingOptions.smoothnessFactor); addOptionWidgetOption(m_sliderSmoothness, m_chkSmooth); addOptionWidgetOption(m_sliderSmoothnessFactor, new QLabel(i18n("Weight:"))); // Drawing assistant configuration m_chkAssistant = new QCheckBox(i18n("Assistant:"), optionWidget); ... ... @@ -78,7 +114,7 @@ QWidget * KisToolBrush::createOptionWidget() connect(m_chkAssistant, SIGNAL(toggled(bool)), this, SLOT(setAssistant(bool))); m_sliderMagnetism = new KisSliderSpinBox(optionWidget); m_sliderMagnetism->setToolTip(i18n("Assistant Magnetism")); m_sliderMagnetism->setRange(0, MAXIMUM_SMOOTHNESS); m_sliderMagnetism->setRange(0, MAXIMUM_MAGNETISM); m_sliderMagnetism->setEnabled(false); connect(m_chkAssistant, SIGNAL(toggled(bool)), m_sliderMagnetism, SLOT(setEnabled(bool))); m_sliderMagnetism->setValue(m_magnetism * MAXIMUM_MAGNETISM); ... ...
 ... ... @@ -32,6 +32,7 @@ class QGridLayout; class KoCanvasBase; class KisSliderSpinBox; class KisDoubleSliderSpinBox; class KisToolBrush : public KisToolFreehand { ... ... @@ -44,15 +45,19 @@ public: QWidget * createOptionWidget(); private slots: void slotSetSmoothness(int smoothness); void slotSetSmoothnessQuality(int quality); void slotSetSmoothnessFactor(qreal factor); void slotSetMagnetism(int magnetism); void slotSetSmoothingType(int index); private: QGridLayout *m_optionLayout; QCheckBox *m_chkSmooth; QComboBox *m_cmbSmoothingType; QCheckBox *m_chkAssistant; KisSliderSpinBox *m_sliderMagnetism; KisSliderSpinBox *m_sliderSmoothness; KisDoubleSliderSpinBox *m_sliderSmoothnessFactor; KisSliderSpinBox *m_sliderSmoothnessQuality; }; ... ...
 ... ... @@ -147,6 +147,7 @@ set(kritaui_LIB_SRCS tool/kis_tool_polyline_base.cpp tool/kis_color_picker_utils.cpp tool/kis_resources_snapshot.cpp tool/kis_smoothing_options.cpp tool/strokes/freehand_stroke.cpp tool/strokes/kis_painter_based_stroke_strategy.cpp widgets/kis_channelflags_widget.cpp ... ...
 /* * Copyright (c) 2012 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_smoothing_options.h" KisSmoothingOptions::KisSmoothingOptions() : smoothingType(WEIGHTED_SMOOTHING) , smoothnessFactor(50.0) , smoothnessQuality(20) { }
 /* * Copyright (c) 2012 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIS_SMOOTHING_OPTIONS_H #define KIS_SMOOTHING_OPTIONS_H #include struct KisSmoothingOptions { enum SmoothingType { NO_SMOOTHING = 0, SIMPLE_SMOOTHING, WEIGHTED_SMOOTHING }; KisSmoothingOptions(); SmoothingType smoothingType; qreal smoothnessFactor; int smoothnessQuality; }; #endif // KIS_SMOOTHING_OPTIONS_H
 ... ... @@ -71,9 +71,7 @@ KisToolFreehand::KisToolFreehand(KoCanvasBase * canvas, const QCursor & cursor, { m_explicitShowOutline = false; m_smooth = true; m_assistant = false; m_smoothness = 1.0; m_magnetism = 1.0; setSupportOutline(true); ... ... @@ -160,7 +158,7 @@ void KisToolFreehand::initStroke(KoPointerEvent *event) { setCurrentNodeLocked(true); m_helper->setSmoothness(m_smooth, m_smoothness); m_helper->setSmoothness(m_smoothingOptions); m_helper->initPaint(event, canvas()->resourceManager(), image(), image().data(), ... ... @@ -336,11 +334,6 @@ bool KisToolFreehand::wantsAutoScroll() const return false; } void KisToolFreehand::setSmooth(bool smooth) { m_smooth = smooth; } void KisToolFreehand::setAssistant(bool assistant) { m_assistant = assistant; ... ...
 ... ... @@ -25,6 +25,7 @@ #include "kis_resources_snapshot.h" #include "kis_paintop_settings.h" #include "kis_distance_information.h" #include "kis_smoothing_options.h" #include "krita_export.h" ... ... @@ -83,7 +84,6 @@ protected: protected slots: void setSmooth(bool smooth); void setAssistant(bool assistant); private: ... ... @@ -114,8 +114,8 @@ private slots: void hideOutline(); protected: bool m_smooth; double m_smoothness; KisSmoothingOptions m_smoothingOptions; bool m_assistant; double m_magnetism; ... ...