Krita Source Code Documentation
Loading...
Searching...
No Matches
ParticleBrush Class Reference

#include <particle_brush.h>

Public Member Functions

void draw (KisPaintDeviceSP dab, const KoColor &color, const QPointF &pos)
 
void initParticles ()
 
 ParticleBrush ()
 
void setInitialPosition (const QPointF &pos)
 
void setProperties (KisParticleOpOptionData *properties)
 
 ~ParticleBrush ()
 

Private Member Functions

void paintParticle (KisRandomAccessorSP writeAccessor, const KoColorSpace *cs, const QPointF &pos, const KoColor &color, qreal weight, bool respectOpacity)
 

Private Attributes

QVector< qreal > m_acceleration
 
QVector< QPointF > m_particleNextPos
 
QVector< QPointF > m_particlePos
 
KisParticleOpOptionDatam_properties
 

Detailed Description

Definition at line 32 of file particle_brush.h.

Constructor & Destructor Documentation

◆ ParticleBrush()

ParticleBrush::ParticleBrush ( )

Definition at line 21 of file particle_brush.cpp.

22{
23 m_properties = 0;
24}
KisParticleOpOptionData * m_properties

References m_properties.

◆ ~ParticleBrush()

ParticleBrush::~ParticleBrush ( )

Definition at line 26 of file particle_brush.cpp.

27{
28}

Member Function Documentation

◆ draw()

void ParticleBrush::draw ( KisPaintDeviceSP dab,
const KoColor & color,
const QPointF & pos )

When the scale is negative the equation becomes unstable, and the point coordinates grow to infinity, so just limit them in that case.

Generally, the effect of instability might be quite interesting for the painters.

Definition at line 84 of file particle_brush.cpp.

85{
87 const KoColorSpace * cs = dab->colorSpace();
88
89 QRect boundingRect;
90
92 boundingRect = dab->defaultBounds()->bounds();
93 }
94
95 for (int i = 0; i < m_properties->particleIterations; i++) {
96 for (int j = 0; j < m_properties->particleCount; j++) {
97 /*
98 m_time = 0.01;
99 QPointF temp = m_position;
100 QPointF dist = m_position - m_oldPosition;
101 m_position = m_position + (dist + (m_acceleration*m_time*m_time));
102 m_oldPosition = temp;
103 */
104
105 /*
106 QPointF dist = info.pos() - m_position;
107 dist *= 0.3; // scale
108 dist *= 10; // force
109 m_oldPosition += dist;
110 m_oldPosition *= 0.989;
111 m_position = m_position + m_oldPosition * m_time * m_time;
112 */
113
114
115 QPointF dist = pos - m_particlePos[j];
116 dist.setX(dist.x() * m_properties->particleScaleX);
117 dist.setY(dist.y() * m_properties->particleScaleY);
118 dist = dist * m_acceleration[j];
122
132 // If scale is negative, position can easily jump into infinity
133 // and then it won't be caught by contains();
134 // and then it will be passed to the lockless hashtable
135 // and then it will crash.
136 // Hence better to catch infinity here and just not paint anything.
137 QPointF pointF = m_particlePos[j];
138
139 const qint32 max = 2147483600;
140 const qint32 min = -max;
141 bool nearInfinity = pointF.x() < min || pointF.x () > max || pointF.y() < min || pointF.y() > max;
142 bool inside = boundingRect.contains(m_particlePos[j].toPoint());
143
144 if (boundingRect.isEmpty() || (inside && !nearInfinity)) {
145 paintParticle(accessor, cs, m_particlePos[j], color, m_properties->particleWeight, true);
146 }
147
148 }//for j
149 }//for i
150}
virtual QRect bounds() const =0
const KoColorSpace * colorSpace() const
KisDefaultBoundsBaseSP defaultBounds() const
KisRandomAccessorSP createRandomAccessorNG()
QVector< qreal > m_acceleration
QVector< QPointF > m_particleNextPos
QVector< QPointF > m_particlePos
void paintParticle(KisRandomAccessorSP writeAccessor, const KoColorSpace *cs, const QPointF &pos, const KoColor &color, qreal weight, bool respectOpacity)
T min(T a, T b, T c)
constexpr std::enable_if< sizeof...(values)==0, size_t >::type max()
const qreal TIME

References KisDefaultBoundsBase::bounds(), KisPaintDevice::colorSpace(), KisPaintDevice::createRandomAccessorNG(), KisPaintDevice::defaultBounds(), m_acceleration, m_particleNextPos, m_particlePos, m_properties, paintParticle(), KisParticleOpOptionData::particleCount, KisParticleOpOptionData::particleGravity, KisParticleOpOptionData::particleIterations, KisParticleOpOptionData::particleScaleX, KisParticleOpOptionData::particleScaleY, KisParticleOpOptionData::particleWeight, and TIME.

◆ initParticles()

◆ paintParticle()

void ParticleBrush::paintParticle ( KisRandomAccessorSP writeAccessor,
const KoColorSpace * cs,
const QPointF & pos,
const KoColor & color,
qreal weight,
bool respectOpacity )
private

paints wu particle, similar to spray version but you can turn on respecting opacity of the tool and add weight to opacity also the particle respects opacity in the destination pixel buffer

Definition at line 48 of file particle_brush.cpp.

49{
50 // opacity top left, right, bottom left, right
51 KoColor myColor(color);
52 quint8 opacity = respectOpacity ? myColor.opacityU8() : OPACITY_OPAQUE_U8;
53
54 int ipx = floor(pos.x());
55 int ipy = floor(pos.y());
56 qreal fx = pos.x() - ipx;
57 qreal fy = pos.y() - ipy;
58
59 quint8 btl = qRound((1.0 - fx) * (1.0 - fy) * opacity * weight);
60 quint8 btr = qRound((fx) * (1.0 - fy) * opacity * weight);
61 quint8 bbl = qRound((1.0 - fx) * (fy) * opacity * weight);
62 quint8 bbr = qRound((fx) * (fy) * opacity * weight);
63
64 accWrite->moveTo(ipx , ipy);
65 myColor.setOpacity(quint8(kisBoundFast<quint16>(OPACITY_TRANSPARENT_U8, btl + cs->opacityU8(accWrite->rawData()), OPACITY_OPAQUE_U8)));
66 memcpy(accWrite->rawData(), myColor.data(), cs->pixelSize());
67
68 accWrite->moveTo(ipx + 1, ipy);
69 myColor.setOpacity(quint8(kisBoundFast<quint16>(OPACITY_TRANSPARENT_U8, btr + cs->opacityU8(accWrite->rawData()), OPACITY_OPAQUE_U8)));
70 memcpy(accWrite->rawData(), myColor.data(), cs->pixelSize());
71
72 accWrite->moveTo(ipx, ipy + 1);
73 myColor.setOpacity(quint8(kisBoundFast<quint16>(OPACITY_TRANSPARENT_U8, bbl + cs->opacityU8(accWrite->rawData()), OPACITY_OPAQUE_U8)));
74 memcpy(accWrite->rawData(), myColor.data(), cs->pixelSize());
75
76 accWrite->moveTo(ipx + 1, ipy + 1);
77 myColor.setOpacity(quint8(kisBoundFast<quint16>(OPACITY_TRANSPARENT_U8, bbr + cs->opacityU8(accWrite->rawData()), OPACITY_OPAQUE_U8)));
78 memcpy(accWrite->rawData(), myColor.data(), cs->pixelSize());
79}
const quint8 OPACITY_TRANSPARENT_U8
const quint8 OPACITY_OPAQUE_U8
virtual quint32 pixelSize() const =0
virtual quint8 opacityU8(const quint8 *pixel) const =0

References KoColor::data(), KisRandomConstAccessorNG::moveTo(), OPACITY_OPAQUE_U8, OPACITY_TRANSPARENT_U8, KoColor::opacityU8(), KoColorSpace::opacityU8(), KoColorSpace::pixelSize(), KisBaseAccessor::rawData(), and KoColor::setOpacity().

◆ setInitialPosition()

void ParticleBrush::setInitialPosition ( const QPointF & pos)

◆ setProperties()

void ParticleBrush::setProperties ( KisParticleOpOptionData * properties)
inline

Definition at line 43 of file particle_brush.h.

43 {
44 m_properties = properties;
45 }

References m_properties.

Member Data Documentation

◆ m_acceleration

QVector<qreal> ParticleBrush::m_acceleration
private

Definition at line 54 of file particle_brush.h.

◆ m_particleNextPos

QVector<QPointF> ParticleBrush::m_particleNextPos
private

Definition at line 53 of file particle_brush.h.

◆ m_particlePos

QVector<QPointF> ParticleBrush::m_particlePos
private

Definition at line 52 of file particle_brush.h.

◆ m_properties

KisParticleOpOptionData* ParticleBrush::m_properties
private

Definition at line 56 of file particle_brush.h.


The documentation for this class was generated from the following files: