diff --git a/plugins/paintops/watercolor/CMakeLists.txt b/plugins/paintops/watercolor/CMakeLists.txt index 892c2b8..d51d026 100644 --- a/plugins/paintops/watercolor/CMakeLists.txt +++ b/plugins/paintops/watercolor/CMakeLists.txt @@ -2,6 +2,7 @@ set(kritawatercolorpaintop_SOURCES kis_splat.cpp kis_wetmap.cpp kis_base_splats_plane.cpp + kis_base_splats_plane.cpp watercolor_paintop_plugin.cpp kis_watercolor_paintop.cpp kis_watercolor_paintop_settings.cpp diff --git a/plugins/paintops/watercolor/kis_base_splats_plane.cpp b/plugins/paintops/watercolor/kis_base_splats_plane.cpp index 808f62c..9fab72a 100644 --- a/plugins/paintops/watercolor/kis_base_splats_plane.cpp +++ b/plugins/paintops/watercolor/kis_base_splats_plane.cpp @@ -20,25 +20,65 @@ #include "kis_base_splats_plane.h" -KisBaseSplatsPlane::KisBaseSplatsPlane(const KoColorSpace *colorSpace) +KisBaseSplatsPlane::KisBaseSplatsPlane(bool useCaching) + : m_isDirty(true), + m_useCaching(true) { - m_cachedPD = new KisPaintDevice(colorSpace); +} + +KisBaseSplatsPlane::~KisBaseSplatsPlane() +{ + } void KisBaseSplatsPlane::add(KisSplat *splat) { - KisPainter *painter = new KisPainter(m_cachedPD); - splat->doPaint(painter); + m_splats << splat; + setDirty(splat->boundingRect().toAlignedRect()); } void KisBaseSplatsPlane::remove(KisSplat *splat) { - m_cachedPD->clear(splat->boundingRect().toRect()); + m_splats.removeOne(splat); + setDirty(splat->boundingRect().toAlignedRect()); } void KisBaseSplatsPlane::paint(KisPainter *gc, QRect rect) { - gc->bitBlt(rect.topLeft(), - m_cachedPD, - rect); + if (m_useCaching) { + + if (m_isDirty) { + if (!m_cachedPD) { + m_cachedPD = new KisPaintDevice(gc->device()->colorSpace()); + } else { + m_cachedPD.clear(); + } + + KisPainter *painter = new KisPainter(m_cachedPD); + Q_FOREACH (KisSplat *splat, m_splats) { + splat->doPaint(painter); + } + m_isDirty = false; + } + + + gc->bitBlt(rect.topLeft(), + m_cachedPD, + rect); + } else { + Q_FOREACH (KisSplat *splat, m_splats) { + splat->doPaint(gc); + } + } +} + +QRect KisBaseSplatsPlane::update(KisWetMap *wetMap) +{ + return QRect(); +} + +void KisBaseSplatsPlane::setDirty(const QRect &rc) +{ + Q_UNUSED(rc); + m_isDirty = true; } diff --git a/plugins/paintops/watercolor/kis_base_splats_plane.h b/plugins/paintops/watercolor/kis_base_splats_plane.h index 237f602..b0e8679 100644 --- a/plugins/paintops/watercolor/kis_base_splats_plane.h +++ b/plugins/paintops/watercolor/kis_base_splats_plane.h @@ -25,6 +25,7 @@ #include "kis_wetmap.h" #include "kis_paint_device.h" #include +#include /** * Base class for the splats' containers in watercolor @@ -41,8 +42,8 @@ class KisBaseSplatsPlane { public: - KisBaseSplatsPlane(const KoColorSpace* colorSpace); - ~KisBaseSplatsPlane(){} + KisBaseSplatsPlane(bool useCaching); + virtual ~KisBaseSplatsPlane(); /** * @brief add splat to list of splats and paint device @@ -67,9 +68,23 @@ public: * @brief update plane * @param wetMap - base for updating */ - QList update(KisWetMap *wetMap); + virtual QRect update(KisWetMap *wetMap); + + +protected: + + QList::iterator remove(QList::iterator it); + QList m_splats; + + +private: + void setDirty(const QRect &rc); + private: KisPaintDeviceSP m_cachedPD; + bool m_isDirty; + bool m_useCaching; + //KoRTree m_splatsTree; }; #endif // KIS_ABSTRACT_SPLATS_PLANE_H diff --git a/plugins/paintops/watercolor/kis_fixed_splats_plane.cpp b/plugins/paintops/watercolor/kis_fixed_splats_plane.cpp new file mode 100644 index 0000000..fc682ba --- /dev/null +++ b/plugins/paintops/watercolor/kis_fixed_splats_plane.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Dmitry Kazakov + * + * 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_fixed_splats_plane.h" + +KisFixedSplatsPlane::KisFixedSplatsPlane(KisBaseSplatsPlane *driedPlane, KisBaseSplatsPlane *flowingPlane) + : KisBaseSplatsPlane(true), + m_driedPlane(driedPlane), + m_flowingPlane(flowingPlane) +{ +} + +QRect KisFixedSplatsPlane::update(KisWetMap *wetMap) +{ + QRect dirtyRect; + + for (auto it = m_splats.begin(); it != m_splats.end();) { + KisSplat *splat = *it; + + if (splat->update(m_wetMap) == KisSplat::Dried) { + m_driedPlane->add(splat); + { + // move to protected call to parent class + it = m_splats.erase(it); + setDirty(splat->boundingRect()); + } + dirtyRect |= splat->boundingRect(); + } else { + ++it; + } + } + + return dirtyRect; +} + diff --git a/plugins/paintops/watercolor/kis_fixed_splats_plane.h b/plugins/paintops/watercolor/kis_fixed_splats_plane.h new file mode 100644 index 0000000..9c9cd53 --- /dev/null +++ b/plugins/paintops/watercolor/kis_fixed_splats_plane.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Dmitry Kazakov + * + * 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 KISFIXEDSPLATSPLANE_H +#define KISFIXEDSPLATSPLANE_H + +#include "kis_base_splats_plane.h" + +class KisFixedSplatsPlane : public KisBaseSplatsPlane +{ +public: + KisFixedSplatsPlane(KisBaseSplatsPlane *driedPlane, KisBaseSplatsPlane *flowingPlane); + + QRect update(KisWetMap *wetMap) override; + +private: + KisBaseSplatsPlane *m_driedPlane; + KisBaseSplatsPlane *m_flowingPlane; +}; + +#endif // KISFIXEDSPLATSPLANE_H diff --git a/plugins/paintops/watercolor/kis_watercolor_paintop.cpp b/plugins/paintops/watercolor/kis_watercolor_paintop.cpp index 531cd78..ac29987 100644 --- a/plugins/paintops/watercolor/kis_watercolor_paintop.cpp +++ b/plugins/paintops/watercolor/kis_watercolor_paintop.cpp @@ -30,9 +30,9 @@ KisWatercolorPaintOp::KisWatercolorPaintOp(const KisPaintOpSettingsSP settings, KisPainter *painter, KisNodeSP node, KisImageSP image) : KisPaintOp(painter), m_fixedTree(4, 2), - m_driedPlane(painter->device()->colorSpace()), - m_fixedPlane(painter->device()->colorSpace()), - m_flowingPlane(painter->device()->colorSpace()) + m_driedPlane(true), + m_fixedPlane(&m_driedPlane, 0), + m_flowingPlane(false) { Q_UNUSED(image); Q_UNUSED(node); @@ -80,19 +80,25 @@ KisSpacingInformation KisWatercolorPaintOp::paintAt(const KisPaintInformation &i break; } - strategy->generate(&m_flowing, + QList newSplats; + strategy->generate(&newSplats, m_wetMap, info.pos(), m_watercolorOption.radius, painter()->paintColor()); - foreach (KisSplat *splat, m_flowing) { + + m_flowing << newSplats; + + foreach (KisSplat *splat, newSplats) { m_flowingPlane.add(splat); - flowingRect |= splat->boundingRect().toRect(); + flowingRect |= splat->boundingRect().toAlignedRect(); } // Updating system for (int i = 0; i < timeGone / 33; i++) { foreach (KisSplat *splat, m_flowing) { + // todo: check if tree should be updated when splat is changed + if (splat->update(m_wetMap) == KisSplat::Fixed) { m_fixed.push_back(splat); m_fixedTree.insert(splat->boundingRect(), splat); @@ -104,7 +110,10 @@ KisSpacingInformation KisWatercolorPaintOp::paintAt(const KisPaintInformation &i flowingRect |= splat->boundingRect().toRect(); } } - foreach (KisSplat *splat, m_fixed) { + + fixedRect |= m_fixedPlane.update(wetMap); + + /*foreach (KisSplat *splat, m_fixed) { if (splat->update(m_wetMap) == KisSplat::Dried) { m_dried.push_back(splat); m_driedPlane.add(splat); @@ -115,7 +124,7 @@ KisSpacingInformation KisWatercolorPaintOp::paintAt(const KisPaintInformation &i m_fixedPlane.remove(splat); fixedRect |= splat->boundingRect().toRect(); } - } + }*/ m_wetMap->update(); }