10#include <QElapsedTimer>
13#include <klocalizedstring.h>
125 return QPoint(qFloor(pos.x()), qFloor(pos.y()));
131 info.
setPos(QPointF(qreal(pixelPos.x()) + 0.5, qreal(pixelPos.y()) + 0.5));
222 distanceInfo = *buddyDistance;
259 const QPointF &pixelCoords,
381 QVariant::fromValue(pixelPos));
386 QPointF tangent1, QPointF tangent2)
388 if (tangent1.isNull() || tangent2.isNull())
return;
390 const qreal maxSanePoint = 1e6;
392 QPointF controlTarget1;
393 QPointF controlTarget2;
396 QPointF controlDirection1 = pi1.
pos() + tangent1;
397 QPointF controlDirection2 = pi2.
pos() - tangent2;
400 QLineF line1(pi1.
pos(), controlDirection1);
401 QLineF line2(pi2.
pos(), controlDirection2);
405 QLineF line3(controlDirection1, controlDirection2);
406 QLineF line4(pi1.
pos(), pi2.
pos());
408 QPointF intersection;
409 if (line3.intersects(line4, &intersection) == QLineF::BoundedIntersection) {
410 qreal controlLength = line4.length() / 2;
412 line1.setLength(controlLength);
413 line2.setLength(controlLength);
415 controlTarget1 = line1.p2();
416 controlTarget2 = line2.p2();
418 QLineF::IntersectType type = line1.intersects(line2, &intersection);
420 if (type == QLineF::NoIntersection ||
421 intersection.manhattanLength() > maxSanePoint) {
423 intersection = 0.5 * (pi1.
pos() + pi2.
pos());
428 controlTarget1 = intersection;
429 controlTarget2 = intersection;
435 qreal velocity1 = QLineF(QPointF(), tangent1).length();
436 qreal velocity2 = QLineF(QPointF(), tangent2).length();
438 if (velocity1 == 0.0 || velocity2 == 0.0) {
441 warnKrita <<
"WARNING: Basic Smoothing: Velocity is Zero! Please report a bug:" <<
ppVar(velocity1) <<
ppVar(velocity2);
444 qreal similarity = qMin(velocity1/velocity2, velocity2/velocity1);
447 similarity = qMax(similarity, qreal(0.5));
451 coeff *= 1 - qMax(qreal(0.0), similarity - qreal(0.8));
459 if (velocity1 > velocity2) {
460 control1 = pi1.
pos() * (1.0 - coeff) + coeff * controlTarget1;
462 control2 = pi2.
pos() * (1.0 - coeff) + coeff * controlTarget2;
464 control2 = pi2.
pos() * (1.0 - coeff) + coeff * controlTarget2;
466 control1 = pi1.
pos() * (1.0 - coeff) + coeff * controlTarget1;
477 qreal zoomingCoeff = 1.0;
535 prevPos = prevPi.
pos();
540 qreal currentDistance = QVector2D(info.
pos() - prevPos).length();
552 qreal gaussianWeight = 1 / (sqrt(2 *
M_PI) * sigma);
553 qreal gaussianWeight2 = sigma * sigma;
554 qreal distanceSum = 0.0;
555 qreal scaleSum = 0.0;
556 qreal pressure = 0.0;
557 qreal baseRate = 0.0;
561 for (
int i =
m_d->
history.size() - 1; i >= 0; i--) {
568 qreal pressureGrad = 0.0;
569 if (i < m_d->history.size() - 1) {
574 if (pressureGrad > 0.0 ) {
575 pressureGrad *= tailAggressiveness * (1.0 - nextInfo.
pressure());
576 distance += pressureGrad * 3.0 * sigma;
580 if (gaussianWeight2 != 0.0) {
582 rate = gaussianWeight * exp(-distanceSum * distanceSum / (2 * gaussianWeight2));
587 }
else if (baseRate / rate > 100) {
592 x += rate * nextInfo.
pos().x();
593 y += rate * nextInfo.
pos().y();
596 pressure += rate * nextInfo.
pressure();
600 if (scaleSum != 0.0) {
605 pressure /= scaleSum;
609 if ((x != 0.0 && y != 0.0) || (x == info.
pos().x() && y == info.
pos().y())) {
610 info.
setPos(QPointF(x, y));
791 sampleSize = qMax(3, sampleSize);
795 for (
int i = sampleSize; i > 0; i--) {
806 if (delayedPaintEnabled) {
820 lastPaintInfo.
xTilt(),
821 lastPaintInfo.
yTilt(),
832 if (queue.size() > 1) {
833 QQueue<KisPaintInformation>::const_iterator it = queue.constBegin();
834 QQueue<KisPaintInformation>::const_iterator end = queue.constEnd();
844 qreal k = qreal(i - 1) / i;
845 result.KisPaintInformation::mixOtherWithoutTime(k, *it);
851 qreal k = qreal(i - 1) / i;
852 result.KisPaintInformation::mixOtherOnlyPosition(k, *it);
869 for (; it != end; ++it) {
872 bool canPaint =
true;
879 qreal dx = sqrt(
pow2(diff.x()) +
pow2(diff.y()));
895 delayedPaintTodoItems.append(newInfo);
1004 return qMax(1, qFloor(realInterval));
1040 const QPointF &control1,
1041 const QPointF &control2,
1046#ifdef DEBUG_BEZIER_CURVES
1073 pi1, control1, control2, pi2));
1095 const QPointF &control1,
1096 const QPointF &control2,
Eigen::Matrix< double, 4, 2 > R
qreal distance(const QPointF &p1, const QPointF &p2)
@ SupportsContinuedInterstrokeData
void cancelUpdateStream()
void startUpdateStream(KisStrokesFacade *strokesFacade, KisStrokeId strokeId)
int stabilizerSampleSize(bool defaultValue=false) const
bool stabilizerDelayedPaint(bool defaultValue=false) const
void addEllipse(const QPointF ¢er, qreal rx, qreal ry)
void reset(const QPointF &pt)
QPointF pushThroughHistory(const QPointF &pt, qreal zoom)
The KisResourcesSnapshot class takes a snapshot of the various resources like colors and settings use...
void setCurrentNode(KisNodeSP node)
KisPaintOpPresetSP currentPaintOpPreset() const
qreal effectiveZoom() const
qreal airbrushingInterval() const
bool needsAirbrushing() const
bool presetNeedsAsynchronousUpdates() const
bool needsSpacingUpdates() const
void addEvent(const KisPaintInformation &pi)
void addFinishingEvent(int numSamples)
std::pair< iterator, iterator > range() const
void setUpdateOutlineCallback(std::function< void()> requestUpdateOutline)
void update(const QVector< KisPaintInformation > &newPaintInfos)
void setPaintLineCallback(std::function< void(const KisPaintInformation &, const KisPaintInformation &)> paintLine)
bool hasLastPaintInformation() const
void start(const KisPaintInformation &firstPaintInfo)
KisPaintInformation lastPaintInformation() const
virtual KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy)=0
virtual void endStroke(KisStrokeId id)=0
virtual void addJob(KisStrokeId id, KisStrokeJobData *data)=0
virtual bool cancelStroke(KisStrokeId id)=0
QVariant resource(int key) const
void setResource(int key, const QVariant &value)
bool isTouchEvent() const
QSharedPointer< KisSmoothingOptions > KisSmoothingOptionsSP
qreal directionBetweenPoints(const QPointF &p1, const QPointF &p2, qreal defaultAngle)
@ EffectiveZoom
-Used only by painting tools for non-displaying purposes
@ EffectivePhysicalZoom
-Used by tool for displaying purposes
static KisUpdateTimeMonitor * instance()
void reportMouseMove(const QPointF &pos)