Page MenuHome

Grease Pencil v2 Branch
ClosedPublic

Authored by Antonio Vazquez (antoniov) on Jul 19 2016, 11:36 AM.

Diff Detail

Repository
rB Blender

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
Antonio Vazquez (antoniov) marked 14 inline comments as done.Jul 29 2016, 10:11 AM

I will upload a new diff with redesign of the close stroke operator using Severin idea of cyclic drawing. The new operator has 3 options: Close all, Open all, Toggle.

source/blender/editors/gpencil/gpencil_data.c
1111

I have redesign the function with your idea. I will upload a new diff with the toogle drawing idea

Aligorith, the alpha value for selection is not by sculpt brush. It is defined in GP_BrushEdit_Settings struct, just below GP_BRUSHEDIT_FLAG_SELECT_MASK flag field.

This settings are defined in the ToolSetting in gp_sculpt field.

Add comment

source/blender/editors/gpencil/gpencil_data.c
622

I agree that this function must be improved, but I think there are several reasons against doing now:

  1. The function BKE_gpencil_layer_find_frame is the one used in official build and in our test with pepeland's animation (very complex) the response is good.
  2. We are working with a very tight timeframe before 2.78 and change this routine could introduce any bug because is used in many places of the not changed original code.

I think is better go as is today, and later in a small patch improve, this routine.

Add a comment

source/blender/editors/gpencil/gpencil_data.c
768

Sorry, I had misunderstood your comments. I'm going to review this routine because I agree, needs some rewrite.

Julian Eisel (Severin) updated this revision to Diff 7139.EditedJul 29 2016, 7:03 PM
Julian Eisel (Severin) edited edge metadata.
  • Rename close operator and rewrite to use cyclic drawing instead of inserting new points
  • Cleanup: Use editable_gpencil_layer context iterator in join strokes operator
  • Cleanup: Use editable_gpencil_layer context iterator in flip strokes operator
  • Fix error when joining strokes in different layers
  • Cleanup: Rename and recode arrange stroke operator
  • Fix compiling Blenderplayer
  • Use GHash in GP merge OP to avoid O(n^2) lookups
  • Cleanup: Unused var
  • Cleanup stroke_cyclic_toggle OP
  • Minor UI Cleanup
  • Use ED_ prefix for externally used editor functions
  • Hide layer colors in dope sheet
  • Add Join&Copy button to UI panel
  • Minor (uberpicky) optimization to new GPencil freeing functions

Note: These commits are by Antonio and myself, don't want to take all the credit ;)

Julian Eisel (Severin) requested changes to this revision.EditedJul 30 2016, 2:45 AM
Julian Eisel (Severin) edited edge metadata.

Second round of (partially really rough) review. Some more notes:

  • Join OP: I'm not really convinced about this operator. What is the benefit of having 2 strokes joined? If it's just for having them share some settings (thickness, color, etc), wouldn't a copy_settings operator make more sense? For duplicating there's still GPENCIL_OT_duplicate_move. Also note that this breaks the 1 stroke == 1 continuous line idea, making operations such as cyclic_toggle and select_linked behave glitchy (would be good to hear feedback from users and @Joshua Leung (aligorith)).
  • Color OPs: These currently apply to all layers. Either they should affect only the active one, or they should be moved to a different place (mainly speaking about stroke_lock_color and palette_lock_layer).
  • @Joshua Leung (aligorith), noticed some functions, esp. in BKE_gpencil.h don't use the conventional prefix. Is that intentional? (Would propose to cleanup after branch landed)

Overall I think this is almost ready for merge (even though I'd prefer to have more time to go over all details ;) ).

source/blender/editors/gpencil/drawgpencil.c
1664–1668

Why is this disabled?

source/blender/editors/gpencil/gpencil_data.c
1076

Hrmpfff, changing properties from redo panel doesn't work for this OP... Maybe needs both _invoke and _exec functions.

source/blender/editors/gpencil/gpencil_undo.c
114–123

Why is this disabled?

source/blender/makesdna/DNA_gpencil_types.h
237–238

Variables should only be declared as deprecated if they are really only used for compatibility. Right now those are accessed quite often still so I'm not sure if they're deprecated now or not?

source/blender/makesrna/intern/rna_gpencil.c
994–997

"is_xxx" is usually used for read-only variables. Either you make it read-only (RNA_def_property_clear_flag(prop, PROP_EDITABLE)), or change the variable name, e.g. "draw_cyclic".

This revision now requires changes to proceed.Jul 30 2016, 2:45 AM
Julian Eisel (Severin) edited edge metadata.

Some more changes, my previous comment still applies.

  • Correct wrong changes in do_versions
  • Fix unused var warnings
  • Random Cleanup: Whitespace, style, UI descriptions, ...
  • Cleanup: Operator names, descriptions, whitespace, ...
  • Cleanup: Group keymap item definitions together
  • Reduce number of padding dummy variables
  • Remove unneeded BLI_listbase_count call
  • Cleanup: Unneeded flag check, shorten if/else block
  • Fix memory leak when joining strokes

The reason to create the join y mainly due fill. For example, if you draw a comic human face and the strokes are not continuous (for artistic reasons), if you don't join with invisible lines you cannot fill. The join speed up a lot the filling process.

Join&Copy is used to create automatically a duplicate with the current active color.

This is the same technique used by ToonBoom Animate/Harmony.

About change color, this operator must change all layers, not only active. What you propose, change the name of the operator?

Comment Added

source/blender/editors/gpencil/drawgpencil.c
1723

This routine draws an icon in the viewport when you are in continuous drawing. Matias and Daniel were not sure if enabled or not, so I disabled but keep the code because is an option under discussion.

source/blender/editors/gpencil/gpencil_undo.c
114–123

This code can be removed. I'm going to do it.

source/blender/makesdna/DNA_gpencil_types.h
237–238

With the new changes, these variables are not used anymore and only used during conversion. I do not if you consider this as deprecated or not, but the content of these variables is not used.

Add Comment

source/blender/editors/gpencil/gpencil_data.c
826

Not sure change these descriptions is the best. In a lot of software the "Bring to Front", "Send to Back" is the standard text recognized by any artist

Antonio Vazquez (antoniov) edited edge metadata.
  • Add DNA_struct_elem_find check
  • Cleanup: Remone unused code
  • Cleanup: Rename property is_closed to draw_cyclic
  • Change operator thickness_apply to use only active layer
  • Cleanup: Fix comment
  • Fix missing pie menu changes after rename arrange parameter in previous commit
Antonio Vazquez (antoniov) marked 22 inline comments as done.Jul 30 2016, 11:56 AM

Add comment

source/blender/blenkernel/intern/gpencil.c
1260–1264

Not sure we save anything here, anyway we would need a while to find recursive, so the time save must be minimum.

source/blender/blenloader/intern/writefile.c
2677

When I made the changes you requested, a new bug appears in undo operations, so I revert the change. Anyway, the loop must do 6 loops or less.

And for palettes usually does 1 loop only.

source/blender/editors/gpencil/drawgpencil.c
1664–1668

This option is not clear from artist point of view if good or not, so I keep the code and when final decission, we can remove if not necessary.

source/blender/makesdna/DNA_gpencil_types.h
173

palcolor is used during drawing to get a "fast" track of the stroke color and speed up drawing. This information is recalculated when load new files or change the palette.

Looking through a bit more of the code, I came across a few places where it's now iterating over the layers, then the strokes manually, so that we have access to the layer that a stroke belongs to, in order to apply parenting corrections. The problem is that this just makes maintenance worse, in that now you have to modify all the places where this happens (which happens to be most of the tools).

There are two options to solve this:

  1. Using a pair of context-iterator macros - similar to the DRIVER_TARGETS_LOOPER + DRIVER_TARGETS_LOOPER_END pair in BKE_fcurve.h
  2. Using the standard context collection stuff - but instead of having bGPDstroke* entries in there, we instead allocate special structs that contain a pair of points (i.e. bGPDlayer * + bGPDstroke *)
  3. Something akin to the keyframe editing api's - Basically, you have an API call that allows looping over the editable strokes in the current context, and then you supply a callback function with context for doing stuff with those strokes and their points. You could have extra args to specify whether you want to auto-apply all the parent transforms to the points or not.

I lean towards the first one, since the context stuff ends up being used by the Python API too, making it messy to define adhoc pairs of items. Meanwhile, the third one borders on being overkill and a bit heavy handed (not to mention needing a lot more helper functions to make everything work); at this stage, it might be too much trouble to recode everything to work this way, so I'm not keen on doing that here for now.

So, I imagine the context iterator macros to look something like this:

/**
  * Iterate over all editable strokes in the current context, 
  * stopping on each usable layer + stroke pair (i.e. gpl and gps)
  * to perform some operations on the stroke.
  *
  * \param gpl  The identifier to use for the layer of the stroke being processed.
  *                    Choose a suitable value to avoid name clashes.
  * \param gps The identifier to use for current stroke being processed.
  *                    Choose a suitable value to avoid name clashes.
  */
#define GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)                                                  \
   {                                                                                                                             \
       CTX_DATA_BEGIN(C, bGPDlayer*, gpl, editable_gpencil_layers)                            \
       {                                                                                                                         \
           /* calculate difference matrix if parent object */
           float diffmat[4][4];                                                                                           \
           ED_gpencil_parent_location(gpl, diff_mat);                                                        \
           /* loop over strokes */
           for (bGPDstroke *gps = gpl->actframe->strokes.first; gps; gps = gps->next) { \
                /* skip strokes that are invalid for current view */
                if (ED_gpencil_stroke_can_use(C, gps) == false)                                            \
                    continue;                                                                                                 \
                /* check if the color is editable */
                if (ED_gpencil_stroke_color_use(gpl, gps) == false)                                       \
                    continue;                                                                                                 \

/* ... Do Stuff With Strokes ...  */

#define GP_EDITABLE_STROKES_END  \
          }                                                \
    }                                                      \
} (void)0
source/blender/editors/gpencil/gpencil_select.c
1088

Use editable layers iterator here

Second round of (partially really rough) review. Some more notes:

  • Join OP: I'm not really convinced about this operator. What is the benefit of having 2 strokes joined? If it's just for having them share some settings (thickness, color, etc), wouldn't a copy_settings operator make more sense? For duplicating there's still GPENCIL_OT_duplicate_move. Also note that this breaks the 1 stroke == 1 continuous line idea, making operations such as cyclic_toggle and select_linked behave glitchy (would be good to hear feedback from users and @Joshua Leung (aligorith)).

Let's address the two points here separately:

  1. I'm all for the Join operator. In fact, I would've implemented it myself at some point anyway :) The main reason it's useful is when creating fills. Specifically, sometimes it's easier to draw some kinds of strokes one way, and other strokes another way; by allowing users to sketch-out the fill shape in segments makes it easier to create such shapes, as you don't have to start being really careful to not mess up a particularly hairy/complex area that comes at the end of a long stroke.
  1. If the operator does not create links between the different segments that have been joined together, then we might have a bit of a problem. The way I've always thought of a Join operator working is that it would just tack the second stroke onto the end of the points buffer of the first stroke (keeping the start/end points relatively consistent), resulting in a single continuous stroke anyway.
  • @Joshua Leung (aligorith), noticed some functions, esp. in BKE_gpencil.h don't use the conventional prefix. Is that intentional? (Would propose to cleanup after branch landed)

This is something I've never bothered to change (apart from a little "argh!" at some bits of the conventions too ;) So, was it intentional - 50/50 :) But yes, this is something to consider for later and not as part of this patch.

The join operator does exactly this: Join the end of one stroke with the next one.

I have implemented a flip routine to reverse stroke direction in order to join properly the strokes. The routine try to do the flip automatically if necessary, but the result is not perfect in all situations, so I implemented a visual hint to see start and end points and a flip operator. I think we could implement better joining/flipping algorithms in future versions.

Some more code review. Sorry for all the noise with separate comments, but this editor seems to get laggy if I do too many of these in one go :/

  • I just noticed some more potential quirks with the parenting stuff:
    • Specifically, the point should only get transformed when dealing with a 3D stroke. 2D strokes (view or in 2d space) should never get transformed in response to a parent object.
    • Perhaps there might be a case for being able to parent screenspace strokes to empties to jiggle them around - @Daniel Martinez Lara (pepeland) Is this something that would even make any sense in practice? I mean, in the 3d-viewport, you'd just see the empty as being in 3d, but the effect would only be the xy components of that mapped to screenspace... Hmm, maybe it could be useful?
    • (In practice, most of the time this might not really be a problem anymore, since you can't easily set parents for layers from non-3d views)
  • Just out of curiosity, why did you end up storing the names of palettes colors in each stroke instead of just storing the index?
    • With an index, searching for the colors becomes faster (no need to do string comparisons)
    • We also wouldn't need all the "strokename update" functions, and file sizes would be better for this (i.e. a saving of some 64-4 = 60 bytes per stroke! Considering that there are quite a lot of strokes per file... :)
    • Rearranging color order might get messier though, if you want to keep the strokes keeping the colors they currently have. (Otherwise, rearranging might be an interesting way to quickly cycle through different colors)
    • What is current behaviour if you name a color differently in one palette, create some strokes using that color, and then switch to another palette? Or for that matter, if you don't have the same number (or set of names) of colors in each palette (if that's even possible)?
  • Personal preference: But, although we can now declare variables anywhere in the code, could we as much as possible try keeping them near the start of the inner-most block where they are used (Note: block not start of each function - so, where you have an opening curly brace { ). It just makes it easier to figure out what the main variables we're dealing with are (instead of having extra ones suddenly popping up out of nowhere). So for instance, it becomes easier to say - "we're doing a calculation involving 5 vectors - two temp ones (and related to each other), leading to a intermediate result, leading to the final result"
    • Initialising/declaring new vars in for-loops are fine, as long as you only need a single iterator variable. With two (for the "it = next) { next = it->next;" pattern, it's nicer to have them declared together outside the loop),
    • If you're allocating stuff that needs to have had some other calcs done beforehand (e.g. as is common when allocating an array where the number of items to store needs to be calculated) delaying when you declare that variable might also be fine.
release/scripts/startup/bl_ui/properties_grease_pencil_common.py
733

No abbreviations in the operator names. So, maybe gpencil.brush_setup_presets or something like that?

source/blender/editors/gpencil/drawgpencil.c
186–187

Note: After all reviewing is done, this function can be removed, since everything goes via the new function now.

293–294

Just a thought - why are we multiplying the geometry point-by-point by the diff_mat, instead of just baking this into the gl transform stack (i.e. glMultMatrixf(diff_mat)). It's not like the parent transform for a stroke can/will change in the middle of a stroke, so there shouldn't be a need to keep doing this multiplying on the CPU side.

This applies not just for these volumetric point drawing functions (well, maybe in this case we can leave things the way they are, but the standard stroke/fill drawing functions could benefit more I think from having this done on the GL side?)

962

Hmm... maybe it would be clearer if you did this instead:

interp_v3_v3v3(tfill, tintcolor, palcolor->fill, tintcolor[3]);
tfill[3] = palcolor->fill[3] * opacity;
977
copy_v3_v3(tfill, palcolor->fill);
tfill[3] = tintcolor[3];
984

See previous example with interp_v3_v3v3()

source/blender/editors/gpencil/gpencil_data.c
826

Agreed. "Bring to Front" and "Send to Back" are pretty much the standard terminology for these operations everywhere outside Blender. Meanwhile, "Top" and "Bottom" here end up being ambiguous - it could equally be taken to mean the "top of the screen" and "bottom of the screen" instead of stacking/z-order.

source/blender/editors/gpencil/gpencil_utils.c
464

Hmm... any reason why this function is here in editors instead of blenkernel?

This function seems to work a lot like the get frame function, so it may be better suited for blenkernel instead.

489

It would be easier/cleaner to just do:
copy_v4_v4(palcolor->color, gpscolor->color)

584

copy_v3_v3(fpt, &pt->x);

source/blender/makesrna/intern/rna_gpencil.c
1603

Would also suggest having slight difference in size. instead of only using hardcoded color differences here (especially red/green). While many artists likely won't have color blindness issues, it still happens for quite a lot of people out there, so it's better to have some fallbacks for people where this may be an issue.

source/blender/makesrna/intern/rna_scene.c
543

Rename this to rna_GPencilBrush_name_set() to keep it in sync with the property

2106

Tooltip could be more helpful - Probably something about brushes being used to control the line style of new strokes

2161

All angles in Blender should be stored as radians internally, and use a property subtype (PROP_ANGLE ?) so that in the UI it will get displayed in degrees.

source/blender/editors/gpencil/drawgpencil.c
1488

This function can be removed?

source/blender/editors/gpencil/gpencil_brush.c
449

copy_v3_v3

source/blender/editors/gpencil/gpencil_edit.c
151

Hmm... I had to double-check the operator to figure out what this does. @Julian Eisel (Severin), any ideas for a better name for this?

My first idea about colors was to save the index of the color (faster and shorter) but after some test with artists, sometimes they have different number of color in each palette and the order of the colors could be different, so the index is not a solution.

If we lock the palettes to have the same colors in the same order, then we could use the index.

Add comment

source/blender/editors/gpencil/gpencil_edit.c
151

This is a request of pepeland. When you draw a very detailed stroke and sculpt wwith mask enabled, the orange dots are very intrusive. This operator toglle de alpha visibility of the orange dots between 0 and 1 to get a fast hide/show effect.

  • Cleanup: Fix comment
  • Fix operator name after rename
  • Cleanup: Remove unused function
  • Cleanup: Remove unused function
  • Cleanup: Replace lines by matrix multiplication
  • Cleanup: Rename function
  • Cleanup: Use copy_v4_v4 instead of set array
  • Revert "Fix missing pie menu changes after rename arrange parameter in previous commit"
  • Revert arrange options text
  • Fix arrange parameter after revert text commit
  • Cleanup: Style
  • Cleanup: Better tooltip text
  • Use angle in radians internally
  • Make start visual point bigger than end point
Antonio Vazquez (antoniov) marked 18 inline comments as done.Jul 31 2016, 10:42 PM

Add comment

release/scripts/startup/bl_ui/properties_grease_pencil_common.py
733

It was a mistake. The real name was "brush_presets_create"

source/blender/editors/gpencil/gpencil_brush.c
449

Used a mul_v3_m4v3 (I do the same in other functions). It's more compact.

source/blender/editors/gpencil/gpencil_data.c
826

I have reverted the change of the text.

source/blender/makesrna/intern/rna_gpencil.c
1603

Good point, I have missed the blind color issue. I have done the green point bigger than red point.

Antonio Vazquez (antoniov) marked 4 inline comments as done.
  • Replace for loop with layer iterator
  • Cleanup: Remove unused field
  • Cleanup: Create Macro for loop layer and strokes
  • Cleanup: Replace by matrix multiplication
  • Cleanup: Use iterator macro for layers and strokes
Antonio Vazquez (antoniov) marked an inline comment as done.Aug 1 2016, 5:06 PM

I still don't like it that the join OP messes up the 1 stroke == 1 continuous line concept, but I don't see a better way to do it offhand either.

stroke_lock_color and palette_lock_layer both apply to all colors and to all strokes if I understand correctly. However they are placed within options that only apply to the currently active color. I'd either move them on top of the panel (even before the palette selector), or into the toolbar. Can be done after branch is merged.

Another thing to think about before merging: What's up with documentation for release notes and manual?

source/blender/blenkernel/intern/gpencil.c
1260–1264

This comment was referring to gpencil_palettecolor_getbyname which now uses BLI_findstring, so can mark as 'Done'

source/blender/editors/gpencil/gpencil_data.c
826

Right, agree. When I changed this I thought the OP was changing the layer list order so I did some renaming that I undid after realizing what the OP is actually doing. This change must have slipped through.

1076

This is still not working, but can be fixed after patch is in master.

source/blender/editors/gpencil/gpencil_edit.c
151

Would still change the name for this, maybe GPENCIL_OT_selection_highlight_toggle or GPENCIL_OT_selection_opacity_toggle.

source/blender/makesdna/DNA_gpencil_types.h
237–238

These variables are still used in a number of places, not only in file conversion code. If they are only used for file conversion, you should mark them as DNA_DEPRECATED.

Julian Eisel (Severin) requested changes to this revision.Aug 3 2016, 5:10 PM
Julian Eisel (Severin) edited edge metadata.
This revision now requires changes to proceed.Aug 3 2016, 5:10 PM
Antonio Vazquez (antoniov) edited edge metadata.
  • Do not disable continuous drawing when press Enter o ESC
  • Rename operator GPENCIL_OT_hideselect_toggle to GPENCIL_OT_selection_opacity_toggle
  • Fix bug in selection if active frame is NULL
  • Cleanup: Change field comments
  • Cleanup: Replace use of layer color in onion skin
  • Use default color from user preferences when create a new color
Julian Eisel (Severin) edited edge metadata.

A few things to check on here and there still, but good enough to go in. Will commit in a bit.

This revision was automatically updated to reflect the committed changes.

Committed to master :) Thanks for all the hard work @Antonio Vazquez (antoniov), keep up the great work!

Alrighty, so here are some further steps:

  • Documentation TODOs:
    • Release notes
    • Blender manual - This probably means quite some work so maybe some users could help here.
    • Would be really cool to have some of your code design documentation here (we try to get into the habbit of adding code documentation)
  • Fix GPENCIL_OT_stroke_cyclical_set not working with redo
  • Find a better place for stroke_lock_color and palette_lock_layer buttons

About the operator, I think they are in the correct location. Both of them lock/hide colors in the palette, If we move to top, then the artist will not know what colors are affected. These operators are not related to layers, but palette colors.

Maybe the problem is the name of the operators, but not the location in UI panel.