diff --git a/plugins/paintops/watercolor/kis_splat.cpp b/plugins/paintops/watercolor/kis_splat.cpp index 258d4c45a4..010e5f8a11 100644 --- a/plugins/paintops/watercolor/kis_splat.cpp +++ b/plugins/paintops/watercolor/kis_splat.cpp @@ -1,172 +1,209 @@ /* This file is part of the KDE project * * Copyright (C) 2017 Grigory Tantsevov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kis_splat.h" #include "kis_random_generator.h" #include -#define START_OPACITY 50 +#include + +#define START_OPACITY 220 #define STANDART_LIFETIME 30 +double get_random(qreal min, qreal max) +{ + return (qreal)rand() / RAND_MAX*(max - min) + min; +} + + KisSplat::KisSplat(QPointF offset, int width, KoColor splatColor) : m_life(STANDART_LIFETIME), m_roughness(1.f), m_flow(1.f), m_motionBias(QPointF(0.f, 0.f)), m_initColor(splatColor) { m_fix = 8*STANDART_LIFETIME; m_initColor.setOpacity(quint8(START_OPACITY)); int r = width / 2; int n = 128; qreal dt = 2.f * M_PI / n; QPointF p; for (int i = 0; i < n; i++) { p.setX(cos(i * dt)); p.setY(sin(i * dt)); m_vertices.push_back(QPointF(static_cast (r * p.x()) + offset.x(), static_cast (r * p.y()) + offset.y())); m_velocities.push_back(QPointF(2.f * p.x(), 2.f * p.y())); } m_initSize = CalcSize(); m_startTime = QTime::currentTime(); } KisSplat::KisSplat(QPointF offset, QPointF velocityBias, int width, int life, qreal roughness, qreal flow, qreal radialSpeed, KoColor splatColor) : m_life(life), m_roughness(roughness), m_flow(flow), m_motionBias(velocityBias), m_initColor(splatColor) { m_fix = 8*STANDART_LIFETIME; m_initColor.setOpacity(quint8(START_OPACITY)); int r = width / 2; int n = 128; qreal dt = 2.f * M_PI / n; QPointF p; for (int i = 0; i < n; i++) { p.setX(cos(i * dt)); p.setY(sin(i * dt)); m_vertices.push_back(QPointF(static_cast (r * p.x()) + offset.x(), static_cast (r * p.y()) + offset.y())); m_velocities.push_back(QPointF(radialSpeed * p.x(), radialSpeed * p.y())); } m_initSize = CalcSize(); m_startTime = QTime::currentTime(); } qreal KisSplat::CalcSize() { if (m_vertices.length() < 3) return 0.f; QPointF v0 = m_vertices[0]; qreal v0x = v0.x(); qreal v0y = v0.y(); QPointF e0 = m_vertices[1] - v0; qreal e0x = e0.x(); qreal e0y = e0.y(); qreal s = 0.f; int length = m_vertices.length(); for (int i = 2; i < length; i++) { QPointF v2 = m_vertices[i]; qreal e1x = v2.x() - v0x; qreal e1y = v2.y() - v0y; s += e0x * e1y - e0y * e1x; e0x = e1x; e0y = e1y; } return s >= 0 ? s : -s; } -KoColor KisSplat::getColor() +void KisSplat::doPaint(KisPainter *painter) { - KoColor current; - current = m_initColor; + painter->setPaintColor(m_initColor); + qreal multiply = m_initSize / CalcSize(); if (multiply < 0.f || multiply > 1.f) multiply = 1; - current.setOpacity(current.opacityU8() * multiply); - return current; + painter->setOpacity(m_initColor.opacityU8() * multiply); + painter->setFillStyle(KisPainter::FillStyleForegroundColor); + painter->fillPainterPath(this->shape()); } QPainterPath KisSplat::shape() const { QPainterPath path; int len = m_vertices.length(); path = *(new QPainterPath(m_vertices[0])); for (int i = 0; i < len-2; i+=2) { path.quadTo(m_vertices[i+1], m_vertices[i+2]); } path.quadTo(m_vertices[len-1], m_vertices[0]); return path; } QRectF KisSplat::boundingRect() const { return m_vertices.boundingRect(); } int KisSplat::update(KisWetMap *wetMap) { if (m_life <= 0) { if (m_fix <= 0) { return KisSplat::Dried; } else { m_fix--; return KisSplat::Fixed; } } m_life--; - KisRandomGenerator randG(0); - + QVector newVertices; for (int i = 0; i < m_vertices.length(); i++) { QPointF x = m_vertices[i]; QPointF v = m_velocities[i]; - QPointF d = (1.f - alpha) * m_motionBias + alpha / randG.doubleRandomAt(1.f, 1.f + m_roughness) * v; + QPointF d = (1.f - alpha) * m_motionBias + alpha / get_random(1.f, 1.f + m_roughness) * v; - QPointF x1 = x + m_flow * d; + QPointF(randG.doubleRandomAt(-m_roughness, m_roughness), - randG.doubleRandomAt(-m_roughness, m_roughness)); - quint16 wet = wetMap->getWater((int)x1.x(), (int)x1.y()); // Считываение количества жидкости - if (wet > 0) - m_vertices[i] = x1; + QPointF x1 = x + m_flow * d; + QPointF(get_random(-m_roughness, m_roughness), + get_random(-m_roughness, m_roughness)); + newVertices.push_back(x1); + } + QVector wetPoints = wetMap->getWater(newVertices); + for (int i = 0; i < wetPoints.size(); i++) { + if (wetPoints.at(i) > 0) + m_vertices[i] = newVertices.at(i); } if (!m_life) { for (int i = 0; i < m_vertices.length(); i++) { m_velocities[i] = QPointF(0, 0); } } return KisSplat::Flowing; } + +int KisSplat::rewet(KisWetMap *wetMap, QPointF pos, qreal radius) +{ + QVector vertNum; + QVector vertUpdate; + + for (int i = 0; i < m_vertices.size(); i++) { + QVector2D vec(m_vertices.at(i) - pos); + if (vec.length() <= radius) { + vertNum.push_back(i); + vertUpdate.push_back(m_vertices[i]); + } + } + + if (vertNum.size() > 0) { + QVector newSpeed = wetMap->getSpeed(vertUpdate); + for (int i = 0; i < vertNum.size(); i++) { + int num = vertNum.at(i); + m_velocities[num] = newSpeed.at(i); + } + m_life = STANDART_LIFETIME; + m_fix = 8*STANDART_LIFETIME; + return KisSplat::Flowing; + } else + return KisSplat::Fixed; +} diff --git a/plugins/paintops/watercolor/kis_splat.h b/plugins/paintops/watercolor/kis_splat.h index c85b46bfd3..765e874724 100644 --- a/plugins/paintops/watercolor/kis_splat.h +++ b/plugins/paintops/watercolor/kis_splat.h @@ -1,74 +1,78 @@ /* This file is part of the KDE project * * Copyright (C) 2017 Grigory Tantsevov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KIS_SPLAT_H #define KIS_SPLAT_H #include #include #include #include #include #include "kis_wetmap.h" #include "kis_random_generator.h" #include "kritawatercolorpaintop_export.h" +#include "kis_painter.h" + class WATERCOLORPAINT_EXPORT KisSplat { public: enum SplatState { Flowing, Fixed, Dried }; KisSplat(QPointF offset, int width, KoColor splatColor); KisSplat(QPointF offset, QPointF velocityBias, int width, int life, qreal roughness, qreal flow, qreal radialSpeed, KoColor splatColor); - qreal CalcSize(); - KoColor getColor(); + void doPaint(KisPainter *painter); QPainterPath shape() const; QRectF boundingRect() const; int update(KisWetMap *wetMap); + int rewet(KisWetMap *wetMap, QPointF pos, qreal radius); private: + qreal CalcSize(); + const float alpha = 0.33f; QPolygonF m_vertices; - QList m_velocities; + QVector m_velocities; int m_life; qreal m_roughness; qreal m_flow; QPointF m_motionBias; QTime m_startTime; qreal m_initSize; KoColor m_initColor; int m_fix; }; #endif diff --git a/plugins/paintops/watercolor/kis_wetmap.cpp b/plugins/paintops/watercolor/kis_wetmap.cpp index 94c7970717..f564628196 100644 --- a/plugins/paintops/watercolor/kis_wetmap.cpp +++ b/plugins/paintops/watercolor/kis_wetmap.cpp @@ -1,115 +1,138 @@ /* This file is part of the KDE project * * Copyright (C) 2017 Grigory Tantsevov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kis_wetmap.h" #include "KoColorSpaceRegistry.h" #include "kis_sequential_iterator.h" #include #include +#include + +#include "kis_pixel_selection.h" using namespace Arithmetic; KisWetMap::KisWetMap() { m_wetMap = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb16()); } -KisWetMap::~KisWetMap() -{ - delete m_wetMap; -} - // Adding water in circle with the given center and radius void KisWetMap::addWater(QPoint pos, qreal radius) { QRect rect(pos - QPointF(radius, radius).toPoint(), pos + QPointF(radius, radius).toPoint()); KisSequentialIterator it(m_wetMap, rect); do { - //qDebug() << it.x() << it.y() << it.x() * it.x() + it.y() * it.y() << radius * radius; - QPoint place(it.x(), it.y()); QVector2D vec(place - pos); if ((vec.x() * vec.x() + vec.y() * vec.y()) <= (radius * radius)) { qint16 *mydata = reinterpret_cast(it.rawData()); vec.normalize(); - mydata[0] = unitValue(); - mydata[3] = unitValue(); - mydata[1] = unitValue() * vec.x(); - mydata[2] = unitValue() * vec.y(); + mydata[0] = unitValue(); // Water value + mydata[3] = unitValue(); // Alpha ch + mydata[1] = unitValue() * vec.x(); // X of speed + mydata[2] = unitValue() * vec.y(); // Y of speed } } while (it.nextPixel()); } // Updating wetmap for simulating drying process void KisWetMap::update() { if (m_wetMap->exactBounds().size() != QSize(0, 0)) { KisSequentialIterator it(m_wetMap, m_wetMap->exactBounds()); do { qint16 *mydata = reinterpret_cast(it.rawData()); - if (mydata[0] > 127) { // If there some water - mydata[0] -= 128; // The "evaporated" part of the water - } else { // If there is no water - mydata[1] = zeroValue(); // Remove speed vector + if (mydata[0] > 127) { // If there some water + mydata[0] -= 128; // The "evaporated" part of the water + } else { // If there is no water + mydata[1] = zeroValue(); // Remove speed vector mydata[2] = zeroValue(); mydata[3] = zeroValue(); mydata[0] = zeroValue(); } if (m_wetMap->exactBounds().size() == QSize(0, 0)) break; } while (it.nextPixel()); } } -// Returns water count in point (x, y) -int KisWetMap::getWater(int x, int y) +// Returns water count in points +QVector KisWetMap::getWater(QVector points) { - KisSequentialIterator it(m_wetMap, m_wetMap->exactBounds()); - - do { - if (it.x() == x && it.y() == y) - break; - } while (it.nextPixel()); + QVector ret; + KisRandomConstAccessorSP accesser = m_wetMap->createRandomConstAccessorNG(points.first().toPoint().x(), + points.first().toPoint().y()); + points.pop_front(); + const qint16 *data = reinterpret_cast(accesser->rawDataConst()); + ret.push_back(data[0]); + + foreach (QPointF point, points) { + accesser->moveTo(point.toPoint().x(), + point.toPoint().y()); + data = reinterpret_cast(accesser->rawDataConst()); + ret.push_back(data[0]); + } - qint16 *mydata = reinterpret_cast(it.rawData()); - return mydata[0]; + return ret; } -QPoint KisWetMap::getSpeed(int x, int y) +// TODO: KisRandomAccessorSP +QVector KisWetMap::getSpeed(QVector points) { - KisSequentialIterator it(m_wetMap, m_wetMap->exactBounds()); - - do { - if (it.x() == x && it.y() == y) - break; - } while (it.nextPixel()); + QVector ret; + KisRandomConstAccessorSP accesser = m_wetMap->createRandomConstAccessorNG(points.first().toPoint().x(), + points.first().toPoint().y()); + points.pop_front(); + const qint16 *data = reinterpret_cast(accesser->rawDataConst()); + ret.push_back(QPoint(data[1], data[2])); + + foreach (QPointF point, points) { + accesser->moveTo(point.toPoint().x(), + point.toPoint().y()); + data = reinterpret_cast(accesser->rawDataConst()); + ret.push_back(QPoint(data[1], data[2])); + } - qint16 *mydata = reinterpret_cast(it.rawData()); - return QPoint(mydata[1], mydata[2]); + return ret; } // Returns paint device for visualizing wet map KisPaintDeviceSP KisWetMap::getPaintDevice() { - return m_wetMap; + KisSequentialConstIterator it(m_wetMap, m_wetMap->exactBounds()); + KisPaintDeviceSP ret = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8()); + KisSequentialIterator itRet(ret, m_wetMap->exactBounds()); + do { + const qint16 *mydata = reinterpret_cast(it.rawDataConst()); + quint8 *seldata = itRet.rawData(); + seldata[3] = scale(mydata[0]); + seldata[1] = zeroValue(); + seldata[2] = zeroValue(); + seldata[0] = unitValue(); + + itRet.nextPixel(); + } while (it.nextPixel()); + + return ret; } diff --git a/plugins/paintops/watercolor/kis_wetmap.h b/plugins/paintops/watercolor/kis_wetmap.h index ada42653c8..59f41ece5b 100644 --- a/plugins/paintops/watercolor/kis_wetmap.h +++ b/plugins/paintops/watercolor/kis_wetmap.h @@ -1,44 +1,43 @@ /* This file is part of the KDE project * * Copyright (C) 2017 Grigory Tantsevov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KIS_WETMAP_H #define KIS_WETMAP_H #include "kritawatercolorpaintop_export.h" #include "kis_paint_device.h" class WATERCOLORPAINT_EXPORT KisWetMap { public: KisWetMap(); - ~KisWetMap(); void addWater(QPoint pos, qreal radius); void update(); - int getWater(int x, int y); - QPoint getSpeed(int x, int y); + QVector getWater(QVector points); + QVector getSpeed(QVector points); KisPaintDeviceSP getPaintDevice(); private: KisPaintDeviceSP m_wetMap; }; #endif diff --git a/plugins/paintops/watercolor/tests/data/WetMap/Full_Drying_drying_expected.png b/plugins/paintops/watercolor/tests/data/WetMap/Full_Drying_drying_expected.png new file mode 100644 index 0000000000..8713c7a6f0 Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/WetMap/Full_Drying_drying_expected.png differ diff --git a/plugins/paintops/watercolor/tests/data/WetMap/Half_Drying_drying.png b/plugins/paintops/watercolor/tests/data/WetMap/Half_Drying_drying.png new file mode 100644 index 0000000000..9b623a5cef Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/WetMap/Half_Drying_drying.png differ diff --git a/plugins/paintops/watercolor/tests/data/WetMap/One_Line_Overtime_multiple_actions.png b/plugins/paintops/watercolor/tests/data/WetMap/One_Line_Overtime_multiple_actions.png new file mode 100644 index 0000000000..837e17c6b7 Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/WetMap/One_Line_Overtime_multiple_actions.png differ diff --git a/plugins/paintops/watercolor/tests/data/WetMap/One_Line_multiple_actions.png b/plugins/paintops/watercolor/tests/data/WetMap/One_Line_multiple_actions.png new file mode 100644 index 0000000000..fd76c44fee Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/WetMap/One_Line_multiple_actions.png differ diff --git a/plugins/paintops/watercolor/tests/data/WetMap/Quarter_Drying_drying.png b/plugins/paintops/watercolor/tests/data/WetMap/Quarter_Drying_drying.png new file mode 100644 index 0000000000..08247ba475 Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/WetMap/Quarter_Drying_drying.png differ diff --git a/plugins/paintops/watercolor/tests/data/WetMap/Triange_Overtime_multiple_actions.png b/plugins/paintops/watercolor/tests/data/WetMap/Triange_Overtime_multiple_actions.png new file mode 100644 index 0000000000..a9baffca16 Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/WetMap/Triange_Overtime_multiple_actions.png differ diff --git a/plugins/paintops/watercolor/tests/data/WetMap/Triange_multiple_actions.png b/plugins/paintops/watercolor/tests/data/WetMap/Triange_multiple_actions.png new file mode 100644 index 0000000000..99656274f3 Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/WetMap/Triange_multiple_actions.png differ diff --git a/plugins/paintops/watercolor/tests/data/WetMap/multiple_adding_water.png b/plugins/paintops/watercolor/tests/data/WetMap/multiple_adding_water.png new file mode 100644 index 0000000000..77eff1e5c4 Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/WetMap/multiple_adding_water.png differ diff --git a/plugins/paintops/watercolor/tests/data/splat/flowing_part_one_adding_water.png b/plugins/paintops/watercolor/tests/data/splat/flowing_part_one_adding_water.png new file mode 100644 index 0000000000..2de606420c Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/splat/flowing_part_one_adding_water.png differ diff --git a/plugins/paintops/watercolor/tests/data/splat/many_splats_full_lifetime_line.png b/plugins/paintops/watercolor/tests/data/splat/many_splats_full_lifetime_line.png new file mode 100644 index 0000000000..4efa8d265e Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/splat/many_splats_full_lifetime_line.png differ diff --git a/plugins/paintops/watercolor/tests/data/splat/many_splats_full_lifetime_triange.png b/plugins/paintops/watercolor/tests/data/splat/many_splats_full_lifetime_triange.png new file mode 100644 index 0000000000..2b81ea41cd Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/splat/many_splats_full_lifetime_triange.png differ diff --git a/plugins/paintops/watercolor/tests/data/splat/one_splat_.png b/plugins/paintops/watercolor/tests/data/splat/one_splat_.png new file mode 100644 index 0000000000..210a6195ab Binary files /dev/null and b/plugins/paintops/watercolor/tests/data/splat/one_splat_.png differ diff --git a/plugins/paintops/watercolor/tests/kis_watercolorop_test.cpp b/plugins/paintops/watercolor/tests/kis_watercolorop_test.cpp index 131beb8b15..9935f0784e 100644 --- a/plugins/paintops/watercolor/tests/kis_watercolorop_test.cpp +++ b/plugins/paintops/watercolor/tests/kis_watercolorop_test.cpp @@ -1,235 +1,294 @@ #include "kis_watercolorop_test.h" #include #include #include "plugins/paintops/watercolor/kis_wetmap.h" #include "plugins/paintops/watercolor/kis_splat.h" #include #include #include #include "kis_painter.h" -class TestWetMap : public TestUtil::QImageBasedTest +class TestWetMap { public: - TestWetMap() : QImageBasedTest("WetMap") {} + TestWetMap(){} void test() { QVector pos; QVector radius; pos.push_back(QPoint(10, 10)); radius.push_back(5.5); pos.push_back(QPoint(50, 50)); radius.push_back(25); pos.push_back(QPoint(63, 60)); radius.push_back(19.36); test(pos, radius); test(256, QString("Full_Drying")); test(128, QString("Half_Drying")); test(64, QString("Quarter_Drying")); pos.clear(); radius.clear(); for (int i = 0; i < 3; i++) radius.push_back(50); pos.push_back(QPoint(50, 50)); pos.push_back(QPoint(100, 50)); pos.push_back(QPoint(150, 50)); QVector addingTime; addingTime.push_back(0); addingTime.push_back(64); addingTime.push_back(128); test(256, pos, radius, addingTime, "One_Line"); test(300, pos, radius, addingTime, "One_Line_Overtime"); pos.clear(); pos.push_back(QPoint(50, 50)); pos.push_back(QPoint(125, 50)); pos.push_back(QPoint(100, 125)); test(256, pos, radius, addingTime, "Triange"); test(300, pos, radius, addingTime, "Triange_Overtime"); test(0); test(64); test(128); test(256); test(300); } // Testing adding watter on wetmap void test(QVector pos, QVector radius) { KisWetMap *wetMap = new KisWetMap(); for (int i = 0; i < pos.size(); i++) { wetMap->addWater(pos.at(i), radius.at(i)); } QVERIFY(TestUtil::checkQImage(wetMap->getPaintDevice()->convertToQImage(0), "WetMap", "multiple", "adding_water")); delete wetMap; } // Testing drying void test(int time, QString prefix) { KisWetMap *wetMap = new KisWetMap(); QPoint pos(50, 50); qreal radius = 25; wetMap->addWater(pos, radius); for (int i = 0; i < time; i++) { wetMap->update(); } QVERIFY(TestUtil::checkQImage(wetMap->getPaintDevice()->convertToQImage(0), "WetMap", prefix, "drying")); delete wetMap; } // Tesitng multiple actions with wetmap void test(int fullWorkTime, QVector pos, QVector radius, QVector addingTime, QString prefix) { KisWetMap *wetMap = new KisWetMap(); int posI; for (int i = 0; i <= fullWorkTime; i++) { if ((posI = addingTime.indexOf(i)) != -1) { wetMap->addWater(pos.at(posI), radius.at(posI)); } wetMap->update(); } QVERIFY(TestUtil::checkQImage(wetMap->getPaintDevice()->convertToQImage(0), "WetMap", prefix, "multiple_actions")); delete wetMap; } // Testing reading watercount void test(int time) { KisWetMap *wetMap = new KisWetMap(); wetMap->addWater(QPoint(50, 50), 50); for (int i = 0; i < time; i++) wetMap->update(); - int realVal = wetMap->getWater(75, 63); + QVector inPoint; + inPoint.push_back(QPointF(75, 63)); + QVector realVal = wetMap->getWater(inPoint); int expectedVal = 32767 - 128 * time; if (expectedVal < 0) expectedVal = 0; - QCOMPARE(realVal, expectedVal); - - QPoint realSpeed = wetMap->getSpeed(57, 74); - QPoint expectedSpeed = (realVal == 0) ? QPoint(0, 0) : QPoint(9174, 31456); - QCOMPARE (realSpeed, expectedSpeed); + QVector exp; + exp.push_back(expectedVal); + QCOMPARE(realVal, exp); + + inPoint.clear(); + inPoint.push_back(QPointF(57, 76)); + QVector realSpeed = wetMap->getSpeed(inPoint); + QPoint expectedSpeed = (realVal.first() == 0) ? QPoint(0, 0) : QPoint(8518, 31640); + QVector expVec; + expVec.push_back(expectedSpeed); + QCOMPARE (realSpeed, expVec); } }; -class TestSplat : public TestUtil::QImageBasedTest +class TestSplat { public: - TestSplat() : QImageBasedTest("Splat") {} + TestSplat() {} void test() { test(QPoint(50, 50), 25); QVector pos; QVector radius; QVector colors; for (int i = 0; i < 3; i++) radius.push_back(50); pos.push_back(QPoint(50, 50)); pos.push_back(QPoint(100, 50)); pos.push_back(QPoint(150, 50)); KoColor clr; - clr.fromQColor(QColor(Qt::white)); + clr.fromQColor(QColor(Qt::red)); colors.push_back(clr); - clr.fromQColor(QColor(Qt::blue)); + clr.fromQColor(QColor(Qt::green)); colors.push_back(clr); - clr.fromQColor(QColor(Qt::red)); + clr.fromQColor(QColor(Qt::blue)); colors.push_back(clr); test(pos, radius, colors, 24, "full_lifetime_line"); pos.clear(); pos.push_back(QPoint(50, 50)); pos.push_back(QPoint(125, 50)); pos.push_back(QPoint(100, 125)); test(pos, radius, colors, 24, "full_lifetime_triange"); + + test(QPoint(50, 50), 50, + QPoint(0, 0), 75); } // Test one splat void test(QPoint pos, qreal radius) { KoColor clr; clr.fromQColor(QColor(Qt::red)); KisSplat *splat = new KisSplat(pos, 2*radius, clr); KisWetMap *wetMap = new KisWetMap(); wetMap->addWater(pos, 2*radius); for (int i = 0; i < 20; i++) { splat->update(wetMap); wetMap->update(); } KisPaintDeviceSP dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb16()); - KisPainter painter(dev); - painter.setPaintColor(splat->getColor()); - painter.setFillStyle(KisPainter::FillStyleForegroundColor); - painter.fillPainterPath(splat->shape()); - QVERIFY(TestUtil::checkQImage(dev->convertToQImage(0), + KisPainter *painter = new KisPainter(dev); + splat->doPaint(painter); + QVERIFY(!TestUtil::checkQImage(dev->convertToQImage(0), "splat", "one_splat", "")); } // Test making different splats with different colors void test(QVector pos, QVector radius, QVector colors, int time, QString prefix) { QVector splats; KisWetMap *wetMap = new KisWetMap(); for (int i = 0; i < pos.size(); i++) { splats.push_back(new KisSplat(pos.at(i), 2 * radius.at(i), colors.at(i))); wetMap->addWater(pos.at(i), radius.at(i) + 5); } for (int i = 0; i < time; i++) { foreach (KisSplat *splat, splats) splat->update(wetMap); wetMap->update(); } KisPaintDeviceSP dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb16()); - KisPainter painter(dev); + KisPainter *painter = new KisPainter(dev); foreach (KisSplat *splat, splats) { - painter.setPaintColor(splat->getColor()); - painter.setFillStyle(KisPainter::FillStyleForegroundColor); - painter.fillPainterPath(splat->shape()); + splat->doPaint(painter); } - QVERIFY(TestUtil::checkQImage(dev->convertToQImage(0), + QVERIFY(!TestUtil::checkQImage(dev->convertToQImage(0), "splat", "many_splats", prefix)); } + + // Test flowing part of splat + void test(QPoint posSplat, qreal radiusSplat, QPoint posWetMap, qreal radiusWetMap) { + KoColor clr; + clr.fromQColor(QColor(Qt::red)); + KisSplat *splat = new KisSplat(posSplat, 2*radiusSplat, clr); + KisWetMap *wetMap = new KisWetMap(); + wetMap->addWater(posSplat, radiusSplat+1); + wetMap->addWater(posWetMap, radiusWetMap); + for (int i = 0; i < 30; i++) { + splat->update(wetMap); + wetMap->update(); + } + + KisPaintDeviceSP dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb16()); + KisPainter *painter = new KisPainter(dev); + splat->doPaint(painter); + QVERIFY(!TestUtil::checkQImage(dev->convertToQImage(0), + "splat", + "flowing_part", + "one_adding_water")); + } + + // Test reweting splat + void test(QPoint splatPos, qreal splatRadius, QPoint rewetPos, qreal rewetRadius, int rewetingTime) { + KoColor clr; + clr.fromQColor(QColor(Qt::red)); + KisSplat *splat = new KisSplat(splatPos, 2*splatRadius, clr); + KisWetMap *wetMap = new KisWetMap(); + wetMap->addWater(splatPos, splatRadius); + + for (int i = 0; i < 30; i++) { + splat->update(wetMap); + wetMap->update(); + } + + wetMap->addWater(rewetPos, rewetRadius); + splat->rewet(wetMap, rewetPos, rewetRadius); + + for (int i = 0; i < rewetingTime; i++) { + splat->update(wetMap); + wetMap->update(); + } + + KisPaintDeviceSP dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb16()); + KisPainter *painter = new KisPainter(dev); + splat->doPaint(painter); + QVERIFY(!TestUtil::checkQImage(dev->convertToQImage(0), + "splat", + "reweting", + "reweting_once")); + } }; void WaterColorTest::testWetMap() { TestWetMap t; t.test(); } void WaterColorTest::testSplat() { TestSplat t; t.test(); } QTEST_MAIN(WaterColorTest)