Implement basic global tablet pressure curve options.
authorAlexander Gavrilov <angavrilov@gmail.com>
Tue, 20 Nov 2018 12:35:59 +0000 (15:35 +0300)
committerAlexander Gavrilov <angavrilov@gmail.com>
Wed, 21 Nov 2018 13:34:07 +0000 (16:34 +0300)
Grease Pencil already implements support for full-featured
per-brush pressure curves, but it is useful to have some
basic global settings that affect all brushes and tools.

This adds two simple options:

- Raw pressure required to achieve full brush intensity.
- Softness control, using a gamma curve internally.

The most important one is the max pressure setting, because it is
critical for ergonomics, but the Linux Wacom driver lacks it.

The softness option internally converts to gamma = 4^-softness.

Reviewers: brecht, campbellbarton

Differential Revision: https://developer.blender.org/D3967

release/scripts/startup/bl_ui/space_userpref.py
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/wm_event_system.h

index 7d8be6ceec01d8bfb3def072c004e46800420b49..e978a86dceaf080fb347611f00e8ac332df1ae69 100644 (file)
@@ -1121,6 +1121,12 @@ class USERPREF_PT_input(Panel):
         sub.prop(walk, "view_height")
         sub.prop(walk, "jump_height")
 
+        sub.separator()
+        sub = layout.column()
+        sub.label(text="Tablet Pressure:")
+        sub.prop(inputs, "pressure_threshold_max")
+        sub.prop(inputs, "pressure_softness")
+
         if inputs.use_ndof:
             layout.separator()
             layout.label(text="NDOF Device:")
index 50bf2f79fdc91f8d83d23d15c2bea898e6bbeaec..f07f9363167fa085e05e076ac460d793f1cd322c 100644 (file)
@@ -8793,6 +8793,11 @@ static void do_versions_userdef(FileData *fd, BlendFileData *bfd)
        if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "gpencil_multisamples")) {
                user->gpencil_multisamples = 4;
        }
+
+       /* tablet pressure threshold */
+       if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "float", "pressure_threshold_max")) {
+               user->pressure_threshold_max = 1.0f;
+       }
 }
 
 static void do_versions(FileData *fd, Library *lib, Main *main)
index 6ae6eaed1c66baa6839c954e5c0e1b4bb39d36ef..c9d163516356e7b72039f5a2694b32638e168251 100644 (file)
@@ -618,6 +618,9 @@ typedef struct UserDef {
        short anisotropic_filter;
        short use_16bit_textures, use_gpu_mipmap;
 
+       float pressure_threshold_max; /* raw tablet pressure that maps to 100% */
+       float pressure_softness;      /* curve non-linearity parameter */
+
        float ndof_sensitivity; /* overall sensitivity of 3D mouse */
        float ndof_orbit_sensitivity;
        float ndof_deadzone; /* deadzone of 3D mouse */
index 15618759ffa078e479260ac250f8873bb6477171..03f86eba601f321763f655d51745a928bddc4d68 100644 (file)
@@ -4582,6 +4582,20 @@ static void rna_def_userdef_input(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Tweak Threshold",
                                 "Number of pixels you have to drag before tweak event is triggered");
 
+       /* tablet pressure curve */
+       prop = RNA_def_property(srna, "pressure_threshold_max", PROP_FLOAT, PROP_FACTOR);
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_float_default(prop, 1.0f);
+       RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.01f, 3);
+       RNA_def_property_ui_text(prop, "Max Threshold",
+                                "Raw input pressure value that is interpreted as 100% by Blender");
+
+       prop = RNA_def_property(srna, "pressure_softness", PROP_FLOAT, PROP_FACTOR);
+       RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+       RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1f, 2);
+       RNA_def_property_ui_text(prop, "Softness",
+                                "Adjusts softness of the low pressure response onset using a gamma curve");
+
 #ifdef WITH_INPUT_NDOF
        /* 3D mouse settings */
        /* global options */
index f82df000288e90b6fa333143f1a08b78fe106743..03a80ff240bbd265992b0aeaf0e16207ccba03b5 100644 (file)
@@ -3662,6 +3662,22 @@ static void wm_eventemulation(wmEvent *event)
        }
 }
 
+/* applies the global tablet pressure correction curve */
+float wm_pressure_curve(float pressure)
+{
+       if (U.pressure_threshold_max != 0.0f) {
+               pressure /= U.pressure_threshold_max;
+       }
+
+       CLAMP(pressure, 0.0f, 1.0f);
+
+       if (U.pressure_softness != 0.0f) {
+               pressure = powf(pressure, powf(4.0f, -U.pressure_softness));
+       }
+
+       return pressure;
+}
+
 /* adds customdata to event */
 static void update_tablet_data(wmWindow *win, wmEvent *event)
 {
@@ -3672,7 +3688,7 @@ static void update_tablet_data(wmWindow *win, wmEvent *event)
                struct wmTabletData *wmtab = MEM_mallocN(sizeof(wmTabletData), "customdata tablet");
 
                wmtab->Active = (int)td->Active;
-               wmtab->Pressure = td->Pressure;
+               wmtab->Pressure = wm_pressure_curve(td->Pressure);
                wmtab->Xtilt = td->Xtilt;
                wmtab->Ytilt = td->Ytilt;
 
index b84b851476ab99011793156ad44dd2f9d6809736..df20dbd8055bb4f38adef707fdf56918a9a567de 100644 (file)
@@ -2014,7 +2014,7 @@ float WM_cursor_pressure(const struct wmWindow *win)
        const GHOST_TabletData *td = GHOST_GetTabletData(win->ghostwin);
        /* if there's tablet data from an active tablet device then add it */
        if ((td != NULL) && td->Active != GHOST_kTabletModeNone) {
-               return td->Pressure;
+               return wm_pressure_curve(td->Pressure);
        }
        else {
                return -1.0f;
index a0610ffcff308b0993239fdec3499e317b49e1b3..fe28cbf9895c7c3d38e3e55c3da1f1cbd848041c 100644 (file)
@@ -101,6 +101,8 @@ void        wm_event_do_depsgraph(bContext *C);
 void        wm_event_do_refresh_wm_and_depsgraph(bContext *C);
 void        wm_event_do_notifiers(bContext *C);
 
+float       wm_pressure_curve(float raw_pressure);
+
 /* wm_keymap.c */
 
 /* wm_dropbox.c */