First step for GSoC: the Painterly Color Mixer.

Boudewijn Rempt boud at valdyas.org
Sun Jun 3 17:03:47 CEST 2007


On Friday 01 June 2007, Emanuele Tamponi wrote:

>     The mixer takes the footprint of the paintop. Then the
>     footprint is mixed with the underlying colors. Optionally, the
>     result is automatically set as the current color of the
>     paintop.

Okay... That could work. You'd need to have three paint devices, then:

* paint mixer canvas paint device (contains all the mixed paint
* dab paint device inside the paintop (you don't do anything with this 
directly, but we need to think (later) about integration of the canvas with 
palette knife and oil bristle brush paintops)
* the temporary paintop the paintop deposits the dab on. This works similar to 
indirect painting in our brush tool.

Also, you'd need to be able to distinguish between paintops that do bidi paint 
transfer (i.e., mix paint themselves) and paintops that don't (i.e, you mix 
the result yourself).

So, you'd have something like

KisPaintDeviceSP mixerCanvas;
canvas->addPainterlyOverlay(wetness);
canvas->addPainterlyOverlay(...);
... (add all painterly overlays

KisPaintDeviceSP paintRecipientCanvas;

paintRecipientCanvasp->addPainterlyOverlay(wetness);
... (add all painterly overlays)

if (paintOp->supportsBidiPaintTransfer()) {
... (copy the rect under event from the mixerCanvas to the 
paintRecipientCanvas, similar the temporary target in KisToolFreehand)
}

KisPainter gc(paintRecipientCanvas)

gc.setPaintOp(currentPaintOp);
gc.paintAt(mouse event location)

(the paintop either perturbs the original data in the paintRecipient or does 
its own thing)
if (!paintOp->supportsBidiPaintTransfer()) {
  mixPaintDevices(paintRecipientCanvas, mixerCanvas);
}



>     To do this, we need to know the nature of the current paintop:
>     we expect that a pencil mixes colors in a different way
>     respect a brush; and this just because the brush is wetter
>     than the pencil.

Either paintops do support mixing by themselves, or they don't -- that's the 
important difference. If they do, then the difference between the new bidi 
enabled pencil paintop and the new bidi enabled brush paintop will come about 
automatically.

>     But current brush and pencil paintops (to make an example)
>     don't have any painterly properties, so the mixer doesn't know
>     about their wetness. On the other hand, there will be some
>     paintops that do have painterly properties.
>     My idea is: for all non-painterly paintops, the mixer guesses
>     about their wetness using their ids. For painterly paintops,
>     the mixer takes their properties using KisPaintOpSettings.

That's a good idea: it could be done in what I temporarily called 
mixPaintDevices(src, dst) above. That method only needs to be called for 
paintops that don't have mixing built-in.

I'd add the supportsBidiPaintTransfer() to KisPaintOp first, with a default 
return value of false. Then implement mixPaintDevices();

>     First issue: we don't want to respect exactly current paintop
>     settings: for example, it's better if we use a different size
>     for the paintop, and, if the current dab of the paintop is a
>     pattern, we will ignore it (we mix colors, not peppers! ;) and
>     take a default color instead.

Sorry, I don't parse... Settings like opacity aren't that interesting, for the 
mixer. The size does matter, but that's automatically done right if you feed 
the paintOp the right pressure settings.

>     Another issue: the bidirectional paintop that I'm going to
>     implement will interfere with the behavior of the mixer. In my
>     opinion, his "bidirectionality" (excuse me for the term :) has
>     to be deactivated while you use it in the mixer.

I think it can replace the default mixing behaviour of the mixer :-)

>     To do all this, my idea is:
>     - While on the mixer, we will change the paintop settings to
>       those set on the paintop (for now, this is just the size of
>       the paintop, but perhaps we will come up to other settings
>       to change).

size is not a paintopsetting: it's something the paintop computes using the 
dab() method from the pressure values it gets from KisPaintInformation object 
you need to create from the data from the pointer event.

>     - Draw the paintop footprint in a white dab (this way, the
>       bidirectional paintop can't do its stuff).
>     - Guess the paintop wetness using its id.
>     - Mix up the color on the dab with the color in the mixer
>       canvas.
>     - Record the changes in wetness that occurs in the canvas.
>     - As user option, automatically set the resulting color as the
>       current paintop color.

>     To clear a frequent equivocal: the mixer doesn't need a
>     painterly overlay! The overlay provides a lot of extra,
>     interactive functions that in a mixer (that just need to *mix*
>     colors) are going to be not useful, if not even not wanted.

I think of adding painterly overlays to the mixer as a kind of "next step". 
However, you cannot record changes in wetness without painterly overlays: 
that's where we store variables like wetness.

I guess that in essence the paint mixer is nothing more than a specialized, 
simplified canvas (only layer only) with a specialized tool, namely one that 
mixes the temporary canvas onto which the paintop paints with the layer 
canvas if the current paintop doesn't implement bidi paint transfer.

Whether it's a good idea to make the painter mixer widget implement 
KoCanvasBase and the mixing tool KoTool is another thing, but I'd be inclined 
to set it up that way.

-- 
Boudewijn Rempt 
http://www.valdyas.org/fading/index.cgi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
Url : http://mail.kde.org/pipermail/kimageshop/attachments/20070603/a7617824/attachment.pgp 


More information about the kimageshop mailing list