GSoC/2020/StatusReports/SaurabhKumar: Difference between revisions
(60 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
==Storyboard Docker For Krita== | ==Storyboard Docker For Krita== | ||
A storyboard is a graphic organizer that consists of illustrations and comments displayed in | ===Project Overview=== | ||
sequence for the purpose of pre-visualizing and planning of motion picture and animation. | A storyboard is a graphic organizer that consists of illustrations and comments displayed in sequence for the purpose of pre-visualizing and planning of motion picture and animation. The project was to implement a docker in Krita that would use the existing animation API in Krita to facilitate storyboarding. Qt's MVC classes are used for storing and displaying the storyboard. | ||
=== | ===Project Goals=== | ||
The requirements of the project can be broken down into the following goals: | |||
* Implementing the basic MVC classes for the docker. | |||
* Integrating relevant parts of Krita, namely the timeline docker and canvas, with the storyboard docker. | |||
* Implementing functionalities to export storyboard as PDF and SVG. | |||
* User documentation. | |||
The mockups prepared for the project: | |||
<gallery mode="slideshow"> | |||
File:Storyboard mockup.png| | |||
File:Storyboard export mockup.png| | |||
File:Storyboard mode view mockup.png| | |||
File:Storyboard export layout mockup.png | |||
</gallery> | |||
===Relevant Code and Technical Pre-requisites=== | |||
====MVC framework==== | |||
This project uses Qt's MVC framework. There are three classes in this framework, model, view and delegate. The model class is an interface for the data, and is used to change and access the data. The delegate class draws the data in the view and lets users edit the data. The view class shows the data as drawn by the delegate. | |||
There are two models in this project, a <code>CommentModel</code> and a <code>StoryboardModel</code>. There are respective view and delegates for those models. <code>StoryboardModel</code>'s data consists of a list of <code>StoryboardItems</code>. The <code>CommentModel</code> controls the number of comment fields in each <code>StoryboardItem</code> of the <code>StoryboardModel</code>'s data. The models are connected using </code>QSignals. | |||
====Krita's Anamtion API==== | |||
=====KisKeyframeChannel===== | |||
An image is stored as a <code>KisImage</code> object in Krita. It has multiple <code>KisNodes</code>. Each <code>KisNode</code> has a <code>KisPaintDevice</code> which contains a <code>KisKeyframeChannel</code>(depending on whether the KisNode is animated or not). These <code>KisKeyframeChannels</code> manage the keyframes in Krita. | |||
=====KisImageAnimationInterface===== | |||
Each <code>KisImage</code> has a <code>KisImageAnimationInterface</code>, which provides an interface for the animation related things of the image, such as framerate or the current time of animation the image is at. | |||
===Work Report=== | |||
====Implementing the MVC classes for the docker==== | |||
=====Week -1 ===== | |||
I started a few weeks early, to cover up for any unprecedented events due to ongoing COVID-19 crisis. This week I added the storyboard docker to Krita's plugin system and implemented the tool-buttons at the top of the docker and the menu related to those buttons. I implemented the CommentModel class to manage the comment tool-button's menu. The members of this menu would be part of the storyboard items that would be part of the storyboard model. I also started implementing the StoryboardModel class. (Commits :[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=8736fd9f3b5c9d718534b41171bcba9d581688e8 1]) | |||
[https://confifu.wordpress.com/2020/05/25/week-1-gsoc-project-report/ Blog post] | |||
=====Week 0===== | |||
[[ | I implemented the delegate class for the CommentModel. I also added a visibility property to members of the CommentModel. This property is shown as an eye icon which can be toggled by clicking. I also implemented the StoryboardItem class that makes up the data of the StoryboardModel and implemented functions in StoryboardModel to manage that data. (Commits : [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=5aca0e09bba2ac06895961fcc468720b6f90a94f 2], [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=6d4c6c7f179f57928dad5dad110d616a84b7dd26 6]) | ||
Also I implemented unit-tests for the CommentModel, StoryboardModel and the interactions between those classes.(Commits: [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=884d20a4b420b39deba4acc19e9cb0bfb60d7caf 3], | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=88d71e6287a7b6abf51bfe9dd8dc8f6162b6f33b 4], [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=b17bb11c8a678e041b9e1771914afb7f341c598b 5]) | |||
[https://confifu.wordpress.com/2020/06/02/week-0-gsoc-project-report/ Blog post] | |||
=== | =====Week 1===== | ||
I implemented the view | |||
(Commit: [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=e32d23261354813f67f8e76e248ff4bf9f6f8f04 9]) and delegate (Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=302fc0f98398008b34e8967e854f0705113fd911 8] [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=d61652c90d9372b544aa52265d9ae0c58048b650 10] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=0e807b51e76fcf725c37e0c6ba797e0b4db52935 11]) classes for the <code>StoryboardModel</code> and debugged <code>StoryboardModel</code>(Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=816fc7e11e00af50cced7545e369eb3843e9bcfc 7]). The <code>StoryboardView</code> class inherits <code>QListView</code> because it has some useful functions, such as <code>setFlow(...)</code> and <code>setWrap(...)</code>, that made implementing View and Modes very easy. | |||
[https://confifu.wordpress.com/2020/06/09/week-1-gsoc-project-report-2/ Blog post] | |||
=====Week 2===== | |||
I implemented the interactions between <code>CommentModel</code> and <code>StoryboardModel</code> | |||
(Commits : | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=65c3a423d0a1ddcec3a80a0ecf5752bb740d977a 12] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=cb3212730eca77e223ae342cb912052d48ab1ada 13] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=c02c86c336d462f5963b0e433a5b31d602c475f2 14]). The interactions are set up so that any comments added to the <code>CommentModel</code> would add rows to each of the items in the <code>StoryboardModel</code>. Similarly with removing or renaming comments. I also implemented the visibility icon's functionality(Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=63790b4c947c5f3b4dd36870ff2c3573b54b74ce 15]). The <code>StoryboardDelegate</code> draws the comment only if its visibility is toggled on in the comment menu. Other than that I implemented the three modes row, column, grid. These modes change the layout of the items in the docker.(Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=fccd367324d8266cba060c495b4de6a8d70daabf 16] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=52a0dd27e7befe5074fd12efc68045e9b7e7b703 17]) | |||
[https://confifu.wordpress.com/2020/06/16/week-2-gsoc-project-report/ Blog post] | |||
=====Week 3===== | |||
I implemented views that decide the part of Storyboard Item visible | |||
(Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=04d8d249208ecd2e17ffbbf8a5daad6e5401186f 18]). There are 3 views Thumbnail only, Comments only and Both. I also implemented drag and drop of Storyboard items (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=dfb9a184d8547d5483dc1da40c4365b540545468 19]). For this I implemented the <code>mimeData</code> and <code>dropMimeData</code> functions and then called the <code>moveRows</code> function in the <code>dropMimeData</code> function to move the rows. I added the right-click menu (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=fbc77f2cf84727fd9f5e3822f0cf0912c9ad8b63 22]) and made the thumbnail's add and delete button functional (Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=905724a64353cdfc97ef4f784ab75949e8e27c5f 20] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=a51c97fe22b0ce93d1e30b1d5154d8b4328b7abc 23]). I modified the unit-tests for the recent changes and ran them successfully (Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=8cdbba61c718671c65ce4d95c55609626537131b 24]). Other than that I fixed some bugs and made some small changes. | |||
(Commits: [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=14e74be154916c0c0798e9d57470ef609e20b9c4 21] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=48d40b91df00a8da8070408be4bb9d152ade3cdd 25] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=fc556d0aa45b49bb92c495f3e7d64bd4d8470fcf 26] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=a6ae05160313342fc381deb24589856c486f8924 27] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=714c35ac1c3a15bcc591c4dc790d5a4bdb79bb87 28]) | |||
[https://confifu.wordpress.com/2020/06/23/week-3-gsoc-project-report/ Blog post] | |||
=====Week 4 and 5===== | |||
I implemented syncing of selections between timeline docker and storyboard docker (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=cb4dda6fe8577052cb931e02ed0cda6746678723 29]) and interactions between timeline docker and storyboard docker such that add, remove and move events in the timeline docker resulted in items being added, removed and moved (Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=1b484651d6fb4b9163794cd096fa7554073bbe2d 31] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=9db959fa36668c3c3c8c725ecabd5cea84c64c6d 33] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=03a0f7a8986a72d7fe74c00bf3e0f2a5c716b7e4 34] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=b8be5e29c4bc18f312379da6c72bb99b4f87161f 35]). | |||
I also implemented updating of current item when frame for that item is changed(Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=f5edf226d09a8892bd9cd6d94efb1c161db86417 30] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=62855495a03be4c9372ecc3802746fef42328fa7 36]). | |||
Other than that I replaced hard-coded values with enums(Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=c4943ef05abdf92a76b7dd572d766ea37dd2a895 32]). | |||
[https://confifu.wordpress.com/2020/07/07/week-4-and-5-gsoc-project-report/ Blog post] | |||
====Integrating relevant parts of Krita with the storyboard docker==== | |||
=====Week 6===== | |||
I started implementing unit-tests for interactions between <code>KisKeyframeChannel</code> and <code>StoryboardModel</code>. The interactions are implemented using <code>QSignals</code>. First, signals are emitted from <code>KisKeyframeChannel</code> to <code>KisImageAnimationInterface</code>. Then <code>KisImageAnimationInterface</code> emits signals which are received by <code>StoryboardModel</code>. These tests are implemented in two parts, first to test signals from <code>KisKeyframeChannel</code> to <code>KisImageAnimationInterface</code> in <code>KisKeyframeAnimationInterfaceSignalTest</code> (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=23a1d3a171672db891bcb7b93fc9617417771ac5 38]) and second to test signals from <code>KisKeyframeChannel</code> to <code>StoryboardModel</code> in <code>StoryboardTimelineSyncTest</code> (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=30cf637ad32d21bed30a4166ae61a796ecc0c755 40])). | |||
I moved some of the connections from <code>StoryboardDockerDock</code> to <code>StoryboardModel</code> to get the tests to work with only a <code>StoryboardModel</code> object (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=9dfe31fdec8df750bd8e29ac6c126fbd89b5b713 39]). Other than that I fixed some bugs.(Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=04b8b500aff09fab4f9e50ec093ceb953dfb0dc4 37]) | |||
[https://confifu.wordpress.com/2020/07/15/week-6-gsoc-project-report/ Blog post] | |||
=====Week 7===== | |||
I added the remaining unit-tests for interactions between timeline and storyboard docker (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=a9c25a7ba0fb00e221280228f8fcf14da3cd1f00 41]) and changed filenames according to conventions used in Krita (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=054b3a79736158becc482fca8b9ef16a1d06e7f4 42]). | |||
Other than that I changed update of thumbnails to occur only when the image is idle, which would improve performance when drawing on canvas (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=8c02d1c207e49fd4db43980ba6a298c5c038bc46 43]) and added some functions for handling rendering of all frames.(Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=cb449f3eca554d8864402846ac96dca883d8fea9 44]) | |||
[https://confifu.wordpress.com/2020/07/21/week-7-gsoc-project-report/ Blog post] | |||
=====Week 8===== | |||
[[ | I implemented the functionality for the duration field (Commit: [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=6ab6f13ade82c66a24c4e43d5563eecdcaff55b6 45]) and addition of storyboard items from storyboard (Commit: [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=24336c5fa965731befec1136bb096c27811179fa 47]). | ||
I implemented the update of all affected items when a keyframe is changed. For this I implemented two classes <code>KisStoryboardThumbnailRenderScheduler</code> and <code>KisAsyncStoryboardThumbnailRenderer</code>. Whenever the <code>KisImage</code> is idle the current frame and all the affected frames are added to queues in <code>KisStoryboardThumbnailRenderScheduler</code>. This class then regenerates and emits <code>KisPaintDevices</code> for those frames one by one using <code>KisAsyncStoryboardThumbnailRenderer</code> which inherits <code>KisAsyncAnimationRendererBase</code>.(Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=e131a0ac1ea2b74871e677605216254059d2107a 48] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=dcc10102b8e0561f28b28113b0e5355bc814be37 49] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=1505f3e69227e2366f98f7ef505ef5e4ce014043 50]). I also posted on Krita Artists asking for feedback. | |||
Other than that hellozee fixed building on Windows and I fixed some bugs. | |||
[[ | (Commits : | ||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=70c078d87ecabf262bf46699262efe6e44854cee 46] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=e56e6cc474410ce550c23cdf2edc8c7aa9a5bd81 51] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=9d1202ecee35cd02ca69315718ee67149a84e3a3 52] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=0a92393348efd8432a5918e8f83d8f17e1a38129 53]) | |||
[https://confifu.wordpress.com/2020/07/29/week-8-gsoc-project-report/ Blog post] | |||
==== | ====Implementing functionalities to export storyboard==== | ||
=====Week 9 and 10===== | |||
I implemented the saving and loading of storyboards. For this I stored a <code>QVector</code> of <code>Comment</code> and a <code>StoryboardItemList</code> in <code>KisDocument</code>. This version of data is kept in sync with the version that is inside <code>CommentModel</code> and <code>StoryboardModel</code>.(Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=1618913cc6012e1195b81bf857f6b7be188333e8 57] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=d7046c380650963081f5be3ecda9840918dab7b0 58] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=4e3b2935de7c1cabaa9c9a27b0782c90a7c45e0a 59] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=2c29f0e18540a4e0b9ca9ac123e2901619e30157 62]) | |||
I also added unit-tests for saving and loading of storyboards. These tests were added in <code>kis_kra_saver_test.cpp</code>. (Commit: [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=65b39c401b2f09b0fb67f319574297e13c0dfc09 56]) | |||
[ | |||
I worked on the <code>Export dialog</code> GUI and implemented some of its functions.(Commits: | |||
[ | [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=21b8fc7a64e8177225f0b6c2e6dc9b795602e316 63] | ||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=f9efa36e85d56066a64616dc39a29e5a15447058 64]) | |||
Other than that I added a patch from Eoin O'Neil, fixed some bugs and merged my branch with master. | |||
[[ | (Commits : | ||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=5f8ba69bb9284df6c887234eb0f0886d6e1cb796 54] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=f06282a73c985dccdb5538dfe9031e657cfc8794 55] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=ecd63406e5163034794125f115e80449d645e0fe 60] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=0453a2a792c296ddaa8d8fd86765d22574e433fd 61] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=ef795a5db0f45bbd2da45e8138f4c36e2dd6c9e6 65] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=e9c349d928ebfa03fb7ac5d6668ffdf3d1ca5750 66]) | |||
[https://confifu.wordpress.com/2020/08/11/week-9-and-10-gsoc-project-report/ Blog post] | |||
=====Week 11 and 12===== | |||
I completed implementing the Export dialog's UI. I added some more options to the Export dialog such as <code>Page Orientation</code> and <code>Font Size</code> (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=23f9c517efb3f52fa0bd1c8b0838ffaae1029f55 74]). I completed both the custom (Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=2c6b61a5ad5c1ec85c8d44a7995c23718168cbc8 67] [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=d636cff623509683a5b226a679bea1a0e03f8970 76]) and SVG layout (Commit: [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=07d40943d5ef710a6b73cb862acbdd1c6a9ab471 77]) specification parts. These are the two options to specify layout for the exported document. I implemented exporting to PDF (Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=764cfa709f96292945dfe75e0318e0275b5b1acb 69] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=c2dfa3df24fb95f72e4ac5a102868d5a98a748b9 75]) and SVG (Commit: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=c91ec8b49cfea4f0b43689e718019e99ee0c1e99 78]) documents. I made some changes based on feedback from Eoin O'Neil(Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=2080150b4cdbb7484363b4c469dd27fa567831c7 70] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=843d1c406b103c2cb046e240913ce42d60f4dfdb 71] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=c41360887a4a9c3c3156cbe6bf959a9022b629a1 72] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=1a8f5f8942593547a5a415320837b1fad569b667 73] [https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=d636cff623509683a5b226a679bea1a0e03f8970 76] | |||
). Other than that I fixed some small bugs. (Commits: | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=865f93ed06b4d701bd91b0f8caf629e5632742c9 68] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=c7a722730eb9aab8db00f637f0e35f08edfdc814 79] | |||
[https://invent.kde.org/graphics/krita/-/merge_requests/392/diffs?commit_id=0fdf81023b11c0f52f1a9a9291009d9e43c5a625 80]) | |||
===Parts completed=== | |||
[[File:Storyboard.png|thumb|center|Storyboard docker]] | |||
* | * Implementing the basic MVC classes for the docker. '''Done''' | ||
* Integrating relevant parts of Krita, namely the timeline docker and canvas, with the storyboard docker. | |||
** Syncing selections '''Done''' | |||
** Add/Remove items in Storyboard docker when keyframes are added/removed in timeline docker '''Done''' | |||
** Move items when keyframes are moved '''Done''' | |||
** Update thumbnails when image is updated '''Done''' | |||
* Implementing functionalities to export storyboard as PDF and SVG. | |||
** Specify Layout using custom options '''Done''' | |||
** Specify layout using SVG file '''Done''' | |||
** Export to SVG file '''Done''' | |||
** Export to PDF file '''Done''' | |||
* Code documentation '''Done''' | |||
* User documentation '''Done''' | |||
The code is not merged due to some bugs and crashes that need to be fixed. | |||
====Update thumbnails on image update==== | |||
{{#ev:youtube|Lp7qwm8mHVQ}} | |||
====Syncing add/remove/move keyframe actions==== | |||
{{#ev:youtube|r_p9tNhfEeE}} | |||
====Menus==== | |||
{|class="tablecenter" style="border: 1px solid grey;" | |||
|[[File:Storyboard comment.png|thumb|center|Comment menu]]||[[File:Arrange menu.png|thumb|center|Arrange menu]] | |||
|} | |||
[[File:Storyboard | ====Views==== | ||
{|class="tablecenter" style="border: 1px solid grey;" | |||
|[[File:Storyboard thumbnail only view.png|thumb|center|Thumbnail Only View]]||[[File:Storyboard comment only view.png|thumb|center|Comment Only View]] | |||
|- | |||
|[[File:Storyboard grid mode.png|thumb|center|Both View]] | |||
|} | |||
====Modes==== | |||
<gallery mode = "slideshow"> | |||
File:Storyboard row mode.png|thumb|center|Row Mode | |||
| | |||
File:Storyboard column mode.png|thumb|center|Column Mode | |||
| | |||
File:Storyboard grid mode.png|thumb|center|Grid Mode | |||
</gallery> | |||
File | ====Layout Specification==== | ||
<gallery mode = "slideshow"> | |||
File:Storyboard custom options.png|center|Layout using custom options | |||
| | |||
File:Storyboard SVG layout.png|center|Layout using SVG file | |||
</gallery> | |||
====User Documentation==== | |||
The link to the documentation MR is [https://invent.kde.org/documentation/docs-krita-org/-/merge_requests/148 here]. The documentation would be merged with the code MR. | |||
===Things to be done=== | |||
* Better syncing of selections between timeline docker and storyboard docker. Highlighted item should always represent the current frame, i.e. what is on the canvas. There are some cases where this is not so. | |||
* Improve usability for multi-layer use. Users would have to create keyframes from the timeline docker if they want to change only the current panel. There should be ways to do that from the storyboard docker itself. | |||
* Make changes in <code>KisStoryboardThumbnailRenderScheduler</code> and <code>KisAsyncStoryboardThumbnailRenderer</code> to fix crashes and improve performance. | |||
===Deliverables=== | ===Deliverables=== |
Latest revision as of 17:29, 28 August 2020
Storyboard Docker For Krita
Project Overview
A storyboard is a graphic organizer that consists of illustrations and comments displayed in sequence for the purpose of pre-visualizing and planning of motion picture and animation. The project was to implement a docker in Krita that would use the existing animation API in Krita to facilitate storyboarding. Qt's MVC classes are used for storing and displaying the storyboard.
Project Goals
The requirements of the project can be broken down into the following goals:
- Implementing the basic MVC classes for the docker.
- Integrating relevant parts of Krita, namely the timeline docker and canvas, with the storyboard docker.
- Implementing functionalities to export storyboard as PDF and SVG.
- User documentation.
The mockups prepared for the project:
Relevant Code and Technical Pre-requisites
MVC framework
This project uses Qt's MVC framework. There are three classes in this framework, model, view and delegate. The model class is an interface for the data, and is used to change and access the data. The delegate class draws the data in the view and lets users edit the data. The view class shows the data as drawn by the delegate.
There are two models in this project, a CommentModel
and a StoryboardModel
. There are respective view and delegates for those models. StoryboardModel
's data consists of a list of StoryboardItems
. The CommentModel
controls the number of comment fields in each StoryboardItem
of the StoryboardModel
's data. The models are connected using QSignals.
Krita's Anamtion API
KisKeyframeChannel
An image is stored as a KisImage
object in Krita. It has multiple KisNodes
. Each KisNode
has a KisPaintDevice
which contains a KisKeyframeChannel
(depending on whether the KisNode is animated or not). These KisKeyframeChannels
manage the keyframes in Krita.
KisImageAnimationInterface
Each KisImage
has a KisImageAnimationInterface
, which provides an interface for the animation related things of the image, such as framerate or the current time of animation the image is at.
Work Report
Implementing the MVC classes for the docker
Week -1
I started a few weeks early, to cover up for any unprecedented events due to ongoing COVID-19 crisis. This week I added the storyboard docker to Krita's plugin system and implemented the tool-buttons at the top of the docker and the menu related to those buttons. I implemented the CommentModel class to manage the comment tool-button's menu. The members of this menu would be part of the storyboard items that would be part of the storyboard model. I also started implementing the StoryboardModel class. (Commits :1)
Week 0
I implemented the delegate class for the CommentModel. I also added a visibility property to members of the CommentModel. This property is shown as an eye icon which can be toggled by clicking. I also implemented the StoryboardItem class that makes up the data of the StoryboardModel and implemented functions in StoryboardModel to manage that data. (Commits : 2, 6)
Also I implemented unit-tests for the CommentModel, StoryboardModel and the interactions between those classes.(Commits: 3, 4, 5)
Week 1
I implemented the view
(Commit: 9) and delegate (Commits:
8 10
11) classes for the StoryboardModel
and debugged StoryboardModel
(Commit:
7). The StoryboardView
class inherits QListView
because it has some useful functions, such as setFlow(...)
and setWrap(...)
, that made implementing View and Modes very easy.
Week 2
I implemented the interactions between CommentModel
and StoryboardModel
(Commits :
12
13
14). The interactions are set up so that any comments added to the CommentModel
would add rows to each of the items in the StoryboardModel
. Similarly with removing or renaming comments. I also implemented the visibility icon's functionality(Commit:
15). The StoryboardDelegate
draws the comment only if its visibility is toggled on in the comment menu. Other than that I implemented the three modes row, column, grid. These modes change the layout of the items in the docker.(Commits:
16
17)
Week 3
I implemented views that decide the part of Storyboard Item visible
(Commit:
18). There are 3 views Thumbnail only, Comments only and Both. I also implemented drag and drop of Storyboard items (Commit:
19). For this I implemented the mimeData
and dropMimeData
functions and then called the moveRows
function in the dropMimeData
function to move the rows. I added the right-click menu (Commit:
22) and made the thumbnail's add and delete button functional (Commits:
20
23). I modified the unit-tests for the recent changes and ran them successfully (Commits:
24). Other than that I fixed some bugs and made some small changes.
(Commits: 21
25
26
27
28)
Week 4 and 5
I implemented syncing of selections between timeline docker and storyboard docker (Commit: 29) and interactions between timeline docker and storyboard docker such that add, remove and move events in the timeline docker resulted in items being added, removed and moved (Commits: 31 33 34 35). I also implemented updating of current item when frame for that item is changed(Commits: 30 36). Other than that I replaced hard-coded values with enums(Commit: 32).
Integrating relevant parts of Krita with the storyboard docker
Week 6
I started implementing unit-tests for interactions between KisKeyframeChannel
and StoryboardModel
. The interactions are implemented using QSignals
. First, signals are emitted from KisKeyframeChannel
to KisImageAnimationInterface
. Then KisImageAnimationInterface
emits signals which are received by StoryboardModel
. These tests are implemented in two parts, first to test signals from KisKeyframeChannel
to KisImageAnimationInterface
in KisKeyframeAnimationInterfaceSignalTest
(Commit:
38) and second to test signals from KisKeyframeChannel
to StoryboardModel
in StoryboardTimelineSyncTest
(Commit:
40)).
I moved some of the connections from StoryboardDockerDock
to StoryboardModel
to get the tests to work with only a StoryboardModel
object (Commit:
39). Other than that I fixed some bugs.(Commit:
37)
Week 7
I added the remaining unit-tests for interactions between timeline and storyboard docker (Commit: 41) and changed filenames according to conventions used in Krita (Commit: 42). Other than that I changed update of thumbnails to occur only when the image is idle, which would improve performance when drawing on canvas (Commit: 43) and added some functions for handling rendering of all frames.(Commit: 44)
Week 8
I implemented the functionality for the duration field (Commit: 45) and addition of storyboard items from storyboard (Commit: 47).
I implemented the update of all affected items when a keyframe is changed. For this I implemented two classes KisStoryboardThumbnailRenderScheduler
and KisAsyncStoryboardThumbnailRenderer
. Whenever the KisImage
is idle the current frame and all the affected frames are added to queues in KisStoryboardThumbnailRenderScheduler
. This class then regenerates and emits KisPaintDevices
for those frames one by one using KisAsyncStoryboardThumbnailRenderer
which inherits KisAsyncAnimationRendererBase
.(Commits:
48
49
50). I also posted on Krita Artists asking for feedback.
Other than that hellozee fixed building on Windows and I fixed some bugs. (Commits : 46 51 52 53)
Implementing functionalities to export storyboard
Week 9 and 10
I implemented the saving and loading of storyboards. For this I stored a QVector
of Comment
and a StoryboardItemList
in KisDocument
. This version of data is kept in sync with the version that is inside CommentModel
and StoryboardModel
.(Commits:
57
58
59
62)
I also added unit-tests for saving and loading of storyboards. These tests were added in kis_kra_saver_test.cpp
. (Commit: 56)
I worked on the Export dialog
GUI and implemented some of its functions.(Commits:
63
64)
Other than that I added a patch from Eoin O'Neil, fixed some bugs and merged my branch with master. (Commits : 54 55 60 61 65 66)
Week 11 and 12
I completed implementing the Export dialog's UI. I added some more options to the Export dialog such as Page Orientation
and Font Size
(Commit:
74). I completed both the custom (Commits:
67 76) and SVG layout (Commit: 77) specification parts. These are the two options to specify layout for the exported document. I implemented exporting to PDF (Commits:
69
75) and SVG (Commit:
78) documents. I made some changes based on feedback from Eoin O'Neil(Commits:
70
71
72
73 76
). Other than that I fixed some small bugs. (Commits:
68
79
80)
Parts completed
![](/images.community/thumb/7/7b/Storyboard.png/300px-Storyboard.png)
- Implementing the basic MVC classes for the docker. Done
- Integrating relevant parts of Krita, namely the timeline docker and canvas, with the storyboard docker.
- Syncing selections Done
- Add/Remove items in Storyboard docker when keyframes are added/removed in timeline docker Done
- Move items when keyframes are moved Done
- Update thumbnails when image is updated Done
- Implementing functionalities to export storyboard as PDF and SVG.
- Specify Layout using custom options Done
- Specify layout using SVG file Done
- Export to SVG file Done
- Export to PDF file Done
- Code documentation Done
- User documentation Done
The code is not merged due to some bugs and crashes that need to be fixed.
Update thumbnails on image update
{{#ev:youtube|Lp7qwm8mHVQ}}
Syncing add/remove/move keyframe actions
{{#ev:youtube|r_p9tNhfEeE}}
Menus
![]() |
![]() |
Views
![]() |
![]() |
![]() |
Modes
Layout Specification
User Documentation
The link to the documentation MR is here. The documentation would be merged with the code MR.
Things to be done
- Better syncing of selections between timeline docker and storyboard docker. Highlighted item should always represent the current frame, i.e. what is on the canvas. There are some cases where this is not so.
- Improve usability for multi-layer use. Users would have to create keyframes from the timeline docker if they want to change only the current panel. There should be ways to do that from the storyboard docker itself.
- Make changes in
KisStoryboardThumbnailRenderScheduler
andKisAsyncStoryboardThumbnailRenderer
to fix crashes and improve performance.
Deliverables
- Link to Phabricator task: T12819
- Krita Artists thread: Storyboard feature plans and mockups
- Merge Request : !392
- Blogs : here