Jump to content

GSoC/2019/StatusReports/Albertoefg

From KDE Community Wiki

Krita: Animated Vector Brush

Summary

  • Project Name: Animated Vector Brush for Krita
  • Proposal: Google Docs Proposal
  • Related blog: albertoefg.info
  • Abstract: This projects aims to implement an Animated Vector Brush for Krita, which uses SVG as a source file for the brush tips. The purpose of an animated brush is to change the brush tips automatically with every dab on the canvas. This allows for a quick way to paint different images, create random and fun designs, and explore new ways to paint that are not easy in physical world. In the other hand, using SVG as a source makes it easy to share the brush tips as they are saved as plain text, as opposed to raster image brushes.

Project Goals

  • Write documentation for end users as per the Krita Contribution Guide.
  • Define the structure of the SVG file containing the source tips for the Animated Vector Brush
  • Load AVB
  • Parse SVG
  • Render brush tips as images
  • Write a parasite class to hold the index
  • Write a VectorAnimatedBrush class
  • Write a VectorShapeObject class
  • Write a helper class to populate the VectorAnimatedBrush class
  • Change brush tip with every dab

Project related links

Implementations Status

Write documentation

  • Goal: The documentation should be written for end users as per the Krita Contribution Guide, it should also be sufficient for the users to understand and use the brush.
  • Status: The documentation is mostly done, it is only necessary to add the proper screenshots and update in case of changes.
  • TODO: Add screenshots.
  • Related blog post: My first two weeks on Google Summer of Code

Commits and Differentials

Load AVB

  • Goal: The Animated Vector Brush file should be loaded and call the proper class, in this case KisVectorAnimatedBrush.
  • Status: The implementation is done, the loading of the AVB by the user is using the +import tab.
  • Related blog post: My first two weeks on Google Summer of Code

Commits and Differentials


Parse SVG

  • Goal: The SVG should be parsed and transformed to KoShape as necessary, so Krita can use them to set brushTipImage, paint dabs or change the size of the brush tip.
  • Status: Done.
  • Related blog post: Basic functionality almost ready

Commits and Differentials

Render brush tips as images

  • Goal: The KoShapes should be transformed to QImage as necessary, so Krita can use them to set brushTipImage, paint dabs or change the size of the brush tip.
  • Status: Done.
  • Related blog post: Basic functionality almost ready

Commits and Differentials

Write a parasite class to hold the index

  • Goal: Write a parasite class that will aid KisVectorAnimatedBrush class, holding the values of the Index and related data.
  • Status: In Progress. Although the majority of the class works now, there is a need for comments and cleaning. It can also be extended to add more functionality like different types of sequences: tilt, velocity, etc.
  • Related blog post: Implementing a derivated class of kis_brushes_pipe

Commits and Differentials


Write a KisVectorAnimatedBrush class

Commits and Differentials

Write a VectorShapeObject class

  • Goal: Write a class that will work as a single brush that will hold a single KoShape and a single QImage. A series of objects of this class will populate the VectorAnimatedBrush class, using the KisVectorHelperPipe class.
  • Status: Done.
  • Related blog post: Krita Sprint News

Commits and Differentials

Write a Helper Pipe class to populate the KisVectorAnimatedBrush

  • Goal: Write a helper class for KisVectorAnimatedBrush that will aid holding a parasite object of the class written earlier, and populate the pipe brush with VectorShapeObject brushes.
  • Status: Done.
  • Related blog post: Krita Sprint News

Commits and Differentials

Change brush tip with every dab

Commits and Differentials

All Commits


Chronicle

Community Bonding Period

During this period of the Google Summer of Code I tried to contribute to Krita in different ways, including helping users on IRC and Reddit, and also improving the Krita documentation.

The biggest amount of work I did was to contribute with the Selections Tools section of the manual, as suggested by Wolthera van Hövell. This helped me to understand better how to write documentation, how to use git and gitlab, and how to work with an Open Source project. My work was merged right before the Google Summer of Code started. Link to the closed merge request

First two weeks

During this period I wrote the documentation for my brush. I don't have experience with writing real world software, but I've read it is always a good idea to start writing the end user documentation, this way there is a clear path on what to achieve at the end of the project.

I also read the specification on Scalable Vector Graphics (SVG) 1.1, because I wanted to know as much as I could about the <symbol> and <use> elements. Upon reading this with more detail, I realized it would be a bad idea to use <symbol> for this type of brushes.

This is because ‘symbol’ elements are never rendered directly; their only usage is as something that can be referenced using the ‘use’ element. Using a <symbol> would imply that the users have a broken workflow when it comes to editing the brush tips, because they won't be able to edit the brush in the Krita canvas, as the canvas should not show <symbol> elements only <use> elements. And changing this behavior would be against the SVG specification.

Because of this, I asked for permission to change the original design of the brush, to use the <g> element instead. This would bring a number of benefits: 1) the brush tips could be open, edited and saved in the Krita canvas; 2) the brush tips could be parsed using the SvgParser from the Flake library. 3) It would simplify the user workflow.

Second and Third weeks

During this period I worked on implementing the base class for my brush and to have the basic functionality, this includes: Opening an AVB with the +import tab, parse the XML from the SVG to be a QList of KoShapes, adding the mimetype of .avb to Krita; during this period I didn't have much trouble with Object Oriented Programming as the majority of the work was using functions and implementing the simple things, not touching classes much.

Fourth and Fifth weeks

This was a harder time, I started to work with classes and to implement the index that will change with every dab, changing the images accordingly. This was the first time I really had to understand the way OOP, and C++ works, it wasn't an easy time for me. I tried to implement a class that inherited from KisBrushesPipe, however I was not successful, but I had some small achievements, I started to understand how a brush pipe should work on Krita, what basic functionality I needed and how to achieve this. During this period my mentor started to work with me closer, to make sure I understood everything and were not completely lost.

Sixth and Seventh weeks

This was a period of darkness, although my mentor was really helpful and patient with me. I started to read more of the Krita codebase, specially to look at how KisBrushesPipe and KisImagePipeBrush work, it was really hard, a lot of the functionality was not obvious to me and there was no easy way to understand it.

My mentor guided me by telling me to work on a single class and not look at those classes for the moment, that way I could start to improve my brush in a simple way, this was a good advice. I stopped trying to implement those things and slowly worked on built a more humble thing. Here is a point where I did my biggest mistake, I didn't write tests. I was feeling really confused and had a lot of new things to understand and work with, and the unit tests only added to the complexity, so I tried to focus on learning more about the work I was doing before adding another layer of complexity to my code.

Eight and Ninth weeks

Finally out of the darkness. During this period thanks to the help of my mentor I started to work slowly to improve my brush, to understand more and more of the code of Krita and to implement more functionality.

This weeks were also the ones when the Krita Sprint happened, so I got to talk to my mentor directly, we did a lot of progress, when the Krita Sprint ended my project had a lot of new classes and functionality. I was able to read the code of KisImagepipebrush and have a much clear idea of what was happening and why.

Unfortunately this wasn't all a victory, I did a huge amount of progress and this two weeks were probably the ones were I learned the most about programming, but I also didn't produce as good code as I wish I could, there were was a lot of code I needed to clean, I still needed to write unit testing and have lots of things to improve. But overall I am quite proud of how much I learned and improved.


Conclusion

Overall the whole I am proud of all the learning and work I did. It has been one of the greatest experiences to learn and collaborate with such an amazing project as Krita, to meet all the team during the Krita Sprint and to realize how much more I can do to help.

I still have a lot to improve my project. Fortunately the end of the Google Summer of Code does not mean the end of my collaboration with Krita, which I hope will last for years to come and I feel proud to be a member of this community.

I have to admit my project is not yet ready to be part of Krita. There are still things to do, it is necessary to clean the code, to add more comments, and to add more tests. But thanks to the progress of the last few weeks I am confident it won't be that long before my brush can become part of Krita.


The future

Talking to my mentor and some other Krita developers, I was suggested to read more programming books, one of them being "Design Patterns: Elements of Reusable Object-Oriented Software". I plan to read this book to learn more and be able to produce better code for Krita.

I was also suggested by Tiar to start writing and small program that would reset the configuration of Krita, to help non-technical users, as suggested by this phabricator task.

Of course I want to keep improving my brush to take it to the next level, adding new features and options that were beyond the scope of the Google Summer of Code period and my coding abilities.