User:HobbesOS/GSOC2021/Proposal

Name
Cian Jinks

Contact

 * Email - cjinks99@gmail.com
 * developer.blender.org - https://developer.blender.org/p/Hobbes/
 * blender.chat - HobbesOS
 * Github - https://github.com/cianjinks

Synopsis
This project will bring a selection of much needed improvements to the knife tool in Blender which will better the modelling workflow of the tool. It proposes such changes as the ability to undo individual steps of the cutting process, a visual measure of distance and angles per cut, more precise angle control in constrained angle mode, the ability to snap cuts to global or local orientation, knife usage in multi-object edit mode and an edge removal mode.

Benefits
In its current state the knife tool is mainly useful for making quick and rough cuts when modelling in Blender. This project aims to give users much more flexibility and precision when it comes to how they choose to use the tool. The changes made will encourage longer use of the tool for more detailed modelling work and will also eliminate many of the current frustration it can cause.

In terms of extensibility, much of the changes will build upon the current code and be designed with future improvements for the knife tool in mind.

Deliverables

 * More precise control over constrained angle mode
 * Use number input and new option to control the angle snapping increment
 * Visible distance and angle measurements when making cuts
 * Ability to undo individual steps of the knife tool cutting process
 * Enable snapping to global and local object orientation in x, y or z direction via keyboard input
 * Use knife tool across multiple objects in multi-object edit mode
 * Remove specific edges of a knife tool cut
 * New edge removal mode

Project Details
As discussed above this project incorporates many smaller tasks into one, each of which will greatly improve on the current knife tool’s capabilities and use cases.

Constrained Angle Mode Improvement
This improvement will make it possible to modify the angle snapping increment in constrained angle mode by either modifying a float value in the Knife Tool options or inputting a float value using the number keys. This will work similarly to how it does for tools such as resize and especially rotate where the user can type a degree value to scale or rotate by respectively.

Currently the snapping angle increment is hardcoded to 45° in the function `knife_snap_angle`. This default value will still be left alone for when a user first enters constrained angle mode, but instead to add it to the Knife Tool settings an RNA float can be defined in `MESH_OT_knife_tool` similar to how `only_selected` is currently defined. When needed the RNA float can be read into a temporary value stored in `KnifeTool_OpData`.

This allows the snapping angle increment to be updated from within the knife tool’s modal function without confirming any change to its value unless needed. Using this, when the user presses number keys it will act as a temporary change to the snapping increment which will then be cleared when constrained angle mode is exited. In contrast, if the user wishes to make a permanent change to the snapping value they can use the tool options panel to do so, as this will directly update the RNA value. Handling of number key presses can be done using the `numinput.c` utility functions.

Note: I have already begun work on this improvement which can be seen here - D10853



Visible Distance and Angle Measurements
This improvement will show the current knife cut angle and distance beside the cut. The user will be able to toggle on and off this feature using a given key, for example `M`, similar to toggling constrained angle mode using the `C` key or completing a cut by hitting enter.

Visually the distance measurement will look very similar to the current measure tool and implementation wise could re-use some of it’s gizmo drawing code. However, when displaying the angle some considerations will need to be taken into account. For example, depending on the number of cut segments there are and where the cut segment begins and ends the angles being displayed will be different. A visual representation of some of the possible cases:



Each case shows which angles will be shown during the cutting process at that point.

Undo Capability
This improvement has been long awaited by the community and will provide the ability to undo single steps of the knife tool cutting process. Currently when a user hits their undo keybind while using the knife tool, nothing happens. Only after they have confirmed the cut can they undo it, in which case the entire cut is removed. This presents two cases where a new undo operation can be introduced:





Implementation wise the first case is arguably easier. The current knife cut data is stored in the `KnifeTool_OpData` struct and so to remove the latest cut segment a variable and/or struct could be added which keeps track of any important information about the most recent segment, such as it’s `KnifeEdge`s and `KnifeVert`s. A utility function such as `knifetool_undo` will then perform the undo operation with the passed in `KnifeTool_OpData`. In this case the knife tool’s modal is running so it would make sense to handle this type of undo operation within it by pressing a key like `U` for example. This would be just like how pressing `C` to enter constrained angle mode is handled.

The second case is more complex. After a user has confirmed their knife tool cut the data stored in `KnifeTool_OpData` is used to create the new edges on the mesh and then is thrown away by the `knifetool_exit_ex` function. Therefore, this data will need to be saved so that it can be restored after the modifications to the mesh are undone. Potentially this can be done through a new undo system type as seen in `undo_system_types.c` to integrate with blender’s current undo stack.

Snapping to Global and Local Orientation
This improvement will allow users to make cuts which are aligned with a given axis either globally or local to the object by pressing the x, y or z key in conjunction with another. Currently toggle cut through is mapped to the z key by default so I propose changing it

Implementing this will be very similar to how constrained angle mode is currently implemented inside `knife_snap_update_from_mval` except using different vector and matrix math to align the current cut in world space or local space.



Multi-Object Edit Mode
This improvement will allow a user to enter edit mode with multiple objects selected and use the knife tool across these multiple objects. Currently when a user tries this they will only be allowed to make cuts on the first of the objects selected. For this to work a user will not be allowed to continue one cut across multiple objects, they will instead have to start new cuts for each of the other objects.

To implement this the current `BMEditMesh` and `Object` pointers contained in `KnifeTool_OpData` will need to be turned into dynamic arrays using blender’s memory utilities. Any added `KnifeEdge`s and `KnifeVert`s will need to be associated with a given mesh from these arrays and many checks will be required to ensure no strange behaviour can occur across cuts.

Individual Edge Removal
This improvement will introduce an edge removal mode to the knife tool. In this mode users will be able to go back and remove any unwanted edges they have made in their cut before it is completed. They will do so by simply clicking on the edge they wish to remove. To enter the mode a key such as `R` may be used.



Implementing the removal of edges will need to already be solved to implement undo capabilities for the knife tool. This only leaves identifying which edge is underneath the mouse cursor while edge removal mode is active. Raycasting into the scene, similar to what is already done when making cuts via `knife_ray_intersect_face` and `knife_input_ray_segment`, should work for this purpose, however it may require a refactoring of how the knife tool stores its edge data to avoid having to loop over a large number of edges.

Project Schedule
From now until June 7th I intend to continue familiarising myself with the blender codebase as I have been doing, through submitting more diffs and interacting with the community. I will also dedicate time to further understanding the current knife tool implementation to the best of my ability. In doing so I will continue to refine my ideas for how each of the improvements outlined in this proposal will be implemented and get started on some of them. Below I have outlined my goal for each of the 10 weeks of this project. Each week I will work 4 hours per day Monday - Friday. (Only time of note is my university exam period is the week beginning 17th of May. I will be done entirely on 20th of May)

Project Plan starting June 7th
After the project period is over I would love to continue working on Blender by fixing any potential bugs my improvements have and to improve the workflow for artists even further over the coming years through the addition of new features.

Bio
My name is Cian Jinks and I am a Computer Science student currently studying at Trinity College Dublin, Ireland. I have been programming since a very young age and used C++ and C as my main languages for the past two years. I have always had a massive interest in computer graphics since I installed Blender for the first time roughly nine years ago. Since then I have used it on and off to create models for projects I was working on, be it games or game addons. In the past two years I have got heavily involved in the programming side of computer graphics. Specifically, I have spent my time working on many personal OpenGL projects to learn the field, which can be seen on my github page. My largest computer graphics project to date was my own 3D modelling software specifically focused around voxels called Voxelio.