[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-kimageshop
Subject:    Re: Future of the animation feature
From:       Dmitry Kazakov <dimula73 () gmail ! com>
Date:       2015-01-25 10:41:43
Message-ID: CAEkBSfVo92GYtX+k7GWJe_0s9To3kZuAUcCoranu8OD=sRTtKQ () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hi, Jouni!

I really like your design. Especially the way you suggest making all the
layer types configurable. Though I'd like to talk about some problems which
might arise.

1) KisNode should not switch KisPaintDeviceSP pointers. Ideally, KisNode's
*public* interface should know nothing about frames and stuff.

Why? Firstly, we store pointers to paint devices of (other) nodes in quiet
a lot of places. The best example is KisCloneLayer. Above that we have lots
of updates and strokes objects that might be queued, so their access to
"switched" nodes will have to be synchronized is some way.

Secondly, no Krita code knows about animation, so its public interfaces
should be as small as possible.

Thirdly, if we switch paint devices directly, how would we handle undo/redo?

Possible solution:

* KisImage knows about frames and has their index. This index is shared
with consumers using KisDefaultBounds interface (see how wraparound mode is
implemented and level-of-detail feature (the latter one is stored
krita-testing-kazakov branch).

* KisNode knows nothing about animation

* KisPaintLayer also knows nothing about animation

* KisPaintDevice knows about animation, can switch it's content (using
switching data managers (see krita-testing-kazakov)) and do
blending/mixing/interpolation for non-key frames (disputable). Current
frame index can be read from KisDefaultBounds provided by the image.

* Switching current frame happens in the image only and can be integrated
into undo/redo.

2) I'm not sure KisFrameCache should belong to KisImage. It fits more to
KisPaintDevice, where all the switching happens.

3) Actually, I would suggest doing this obviously huge project in iteration
approach. That is doing small parts of it sequentially. Like that:

3.1) Implement animation for *paint layers only*. Doing it using
KisImage/KisPaintDevice-only approach would take something about a month of
work and will break almost nothing in Krita. It can also be easily tested
using unittests.

3.2) Implement UI for switching frames and playing it.

// Here we might need to reserve some time for implementing a cache of
already-rendered frames to be able to play them. Straightforward approach
with rendering them on-demand most probably will be too slow.

3.3) Implement saving/loading of such layers

// at this stage we will have a deliverable product that we can even
include in Krita 3.1 or 3.2.

3.4) Port KisTransformMask to already prepared and stable animation
framework.

// at this stage people will be able to use transformations to create
animations.

3.5) Work with other types of layers.




On Sat, Jan 10, 2015 at 8:49 PM, Jouni Pentikäinen <mctyyppi42@gmail.com>
wrote:

>
> Based on the discussion so far, I suggest we try the approach of adding
> time to KisImage.
>
> I propose the following changes (grouped by class). A UML overview of
> these changes is available at https://creately.com/diagram/i3zzekbz1
>
> KisImage
> - Add field for current frame
> - Add method to change current frame. This will call a similar method
>   in the root node of the document.
>
> KisNode
> - Add field for keyframes (KisKeyFrameSequence)
>   - This contains the keyframed data associated with the layer
> - Add method to change current frame. This should recurse into all
>   child nodes.
> - Add method for creating a new keyframe at current frame. This will
>   call writeKeyframe() to get the keyframe data
> - Add virtual methods writeKeyframe and loadKeyframe to get and set
>   data associated with keyframes. These will be implemented in the
>   layer classes to provide and use parameters approriate for the given
>   layer type.
>
> KisKeyFrameSequence (new class)
> - Contains a sequence of keyframes (KisKeyframe)
>
> KisKeyframe (new class)
> - Contains the data associated with a keyframe
> - Data is arbitrary, as provided by the node. It is stored in a
>   KisPropertiesConfiguration.
> - For each property, there is also an associated interpolation mode.
>   This can be used for defining interpolations of continuous functions
>   such as layer opacity.
>
> KisPaintDevice
> - Add method to switch content, requesting the data from KisFrameCache
>
> KisFrameCache (new class)
> - Provides methods for loading raster data (e.g. content of a
>   KisPaintLayer)
> - Maintains a cache of recently used raster data
>
> KisLayer
> - Keyframe data:
>   - Position
>   - Opacity
>
> KisFileLayer
> - Keyframe data:
>   - filename (for image sequences)
>
> KisPaintLayer
> - Keyframe data:
>   - Raster content (trough paintDevice)
>
> KisAdjustmentLayer
> - Keyframe data:
>   - Filter configuration
>
> KisGeneratorLayer
> - Keyframe data:
>   - Filter configuration
>
> KisMask
> - Keyframe data:
>   - Raster content (akin to KisPaintLayer)
>
> KisFilterMask
> - Keyframe data:
>   - Filter configuration
>
> KisTransformMask
> - Keyframe data:
>   - Transform parameters
>
> KisAnimationDoc
> - Refactor playback into UI code
> - Refactor onion skinning into projection code (?)
>
> KisAnimation, KisAnimationStore, KisKranimSaver, KisKranimLoader
> - No longer needed
>
>
> As a sidenode, not all of these changes need to be done at once. As long
> as the basic keyframing system is in place, any layer type which doesn't
> implement keyframes will behave as a static content. "Bells and whistles"
> such as adjustable interpolation curves can be added later as time allows.
>
> The question of file format is still open. A fairly straightforward
> approach would be to serialize keyframes from each KisKeyFrameSequence and
> place them either in a separate entry inside the .kra document (e.g.
> keyframes.xml) or as a series of child nodes for each layer in maindoc.xml.
>
>
> _______________________________________________
> Krita mailing list
> kimageshop@kde.org
> https://mail.kde.org/mailman/listinfo/kimageshop
>



-- 
Dmitry Kazakov

[Attachment #5 (text/html)]

<div dir="ltr"><div><div><div><div><div>Hi, Jouni!<br><br></div>I really like your \
design. Especially the way you suggest making all the layer types configurable. \
Though I&#39;d like to talk about some problems which might \
arise.<br><br></div><div>1) KisNode should not switch KisPaintDeviceSP pointers. \
Ideally, KisNode&#39;s *public* interface should know nothing about frames and \
stuff.<br></div><div><br></div><div>Why? Firstly, we store pointers to paint devices \
of (other) nodes in quiet a lot of places. The best example is KisCloneLayer. Above \
that we have lots of updates and strokes objects that might be queued, so their \
access to &quot;switched&quot; nodes will have to be synchronized is some \
way.<br><br></div><div>Secondly, no Krita code knows about animation, so its public \
interfaces should be as small as possible.<br><br></div><div>Thirdly, if we switch \
paint devices directly, how would we handle \
undo/redo?<br></div><div><br></div><div>Possible \
solution:<br></div><div><br></div><div>* KisImage knows about frames and has their \
index. This index is shared with consumers using KisDefaultBounds interface (see how \
wraparound mode is implemented and level-of-detail feature (the latter one is stored \
krita-testing-kazakov branch).<br></div><br></div>* KisNode knows nothing about \
animation<br><br></div>* KisPaintLayer also knows nothing about \
animation<br><br></div>* KisPaintDevice knows about animation, can switch it&#39;s \
content (using switching data managers (see krita-testing-kazakov)) and do \
blending/mixing/interpolation for non-key frames (disputable). Current frame index \
can be read from KisDefaultBounds provided by the \
image.<br><div><div><div><br></div><div>* Switching current frame happens in the \
image only and can be integrated into undo/redo.<br></div><div><br></div><div>2) \
I&#39;m not sure KisFrameCache should belong to KisImage. It fits more to \
KisPaintDevice, where all the switching  happens.<br></div><div><br></div><div>3) \
Actually, I would suggest doing this obviously huge project in iteration approach. \
That is doing small parts of it sequentially. Like that:<br><br></div><div \
style="margin-left:40px">3.1) Implement animation for *paint layers only*. Doing it \
using KisImage/KisPaintDevice-only approach would take something about a month of \
work and will break almost nothing in Krita. It can also be easily tested using \
unittests.<br><br></div><div style="margin-left:40px">3.2) Implement UI for switching \
frames and playing it.<br><br></div><div style="margin-left:40px">// Here we might \
need to reserve some time for implementing a cache of already-rendered frames to be \
able to play them. Straightforward approach with rendering them on-demand most \
probably will be too slow.<br><br></div><div style="margin-left:40px">3.3) Implement \
saving/loading of such layers<br><br></div><div style="margin-left:40px">// at this \
stage we will have a deliverable product that we can even include in Krita 3.1 or \
3.2.<br><br></div><div style="margin-left:40px">3.4) Port KisTransformMask to already \
prepared and stable animation framework. <br><br></div><div \
style="margin-left:40px">// at this stage people will be able to use transformations \
to create animations.<br><br></div><div style="margin-left:40px">3.5) Work with other \
types of layers.<br></div><div><br></div><div><br><div><br></div></div></div></div></div><div \
class="gmail_extra"><br><div class="gmail_quote">On Sat, Jan 10, 2015 at 8:49 PM, \
Jouni Pentikäinen <span dir="ltr">&lt;<a href="mailto:mctyyppi42@gmail.com" \
target="_blank">mctyyppi42@gmail.com</a>&gt;</span> wrote:<br><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"><br> Based on the discussion so far, I suggest we try the \
approach of adding time to KisImage.<br> <br>
I propose the following changes (grouped by class). A UML overview of these changes \
is available at <a href="https://creately.com/diagram/i3zzekbz1" \
target="_blank">https://creately.com/diagram/<u></u>i3zzekbz1</a><br> <br>
KisImage<br>
- Add field for current frame<br>
- Add method to change current frame. This will call a similar method<br>
   in the root node of the document.<br>
<br>
KisNode<br>
- Add field for keyframes (KisKeyFrameSequence)<br>
   - This contains the keyframed data associated with the layer<br>
- Add method to change current frame. This should recurse into all<br>
   child nodes.<br>
- Add method for creating a new keyframe at current frame. This will<br>
   call writeKeyframe() to get the keyframe data<br>
- Add virtual methods writeKeyframe and loadKeyframe to get and set<br>
   data associated with keyframes. These will be implemented in the<br>
   layer classes to provide and use parameters approriate for the given<br>
   layer type.<br>
<br>
KisKeyFrameSequence (new class)<br>
- Contains a sequence of keyframes (KisKeyframe)<br>
<br>
KisKeyframe (new class)<br>
- Contains the data associated with a keyframe<br>
- Data is arbitrary, as provided by the node. It is stored in a<br>
   KisPropertiesConfiguration.<br>
- For each property, there is also an associated interpolation mode.<br>
   This can be used for defining interpolations of continuous functions<br>
   such as layer opacity.<br>
<br>
KisPaintDevice<br>
- Add method to switch content, requesting the data from KisFrameCache<br>
<br>
KisFrameCache (new class)<br>
- Provides methods for loading raster data (e.g. content of a<br>
   KisPaintLayer)<br>
- Maintains a cache of recently used raster data<br>
<br>
KisLayer<br>
- Keyframe data:<br>
   - Position<br>
   - Opacity<br>
<br>
KisFileLayer<br>
- Keyframe data:<br>
   - filename (for image sequences)<br>
<br>
KisPaintLayer<br>
- Keyframe data:<br>
   - Raster content (trough paintDevice)<br>
<br>
KisAdjustmentLayer<br>
- Keyframe data:<br>
   - Filter configuration<br>
<br>
KisGeneratorLayer<br>
- Keyframe data:<br>
   - Filter configuration<br>
<br>
KisMask<br>
- Keyframe data:<br>
   - Raster content (akin to KisPaintLayer)<br>
<br>
KisFilterMask<br>
- Keyframe data:<br>
   - Filter configuration<br>
<br>
KisTransformMask<br>
- Keyframe data:<br>
   - Transform parameters<br>
<br>
KisAnimationDoc<br>
- Refactor playback into UI code<br>
- Refactor onion skinning into projection code (?)<br>
<br>
KisAnimation, KisAnimationStore, KisKranimSaver, KisKranimLoader<br>
- No longer needed<br>
<br>
<br>
As a sidenode, not all of these changes need to be done at once. As long as the basic \
keyframing system is in place, any layer type which doesn&#39;t implement keyframes \
will behave as a static content. &quot;Bells and whistles&quot; such as adjustable \
interpolation curves can be added later as time allows.<br> <br>
The question of file format is still open. A fairly straightforward approach would be \
to serialize keyframes from each KisKeyFrameSequence and place them either in a \
separate entry inside the .kra document (e.g. keyframes.xml) or as a series of child \
nodes for each layer in maindoc.xml.<div class="HOEnZb"><div class="h5"><br> <br>
______________________________<u></u>_________________<br>
Krita mailing list<br>
<a href="mailto:kimageshop@kde.org" target="_blank">kimageshop@kde.org</a><br>
<a href="https://mail.kde.org/mailman/listinfo/kimageshop" \
target="_blank">https://mail.kde.org/mailman/<u></u>listinfo/kimageshop</a><br> \
</div></div></blockquote></div><br><br clear="all"><br>-- <br><div \
class="gmail_signature">Dmitry Kazakov</div> </div>



_______________________________________________
Krita mailing list
kimageshop@kde.org
https://mail.kde.org/mailman/listinfo/kimageshop


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic