Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Vazquez <blendergit@gmail.com>2020-03-14 18:16:35 +0300
committerAntonio Vazquez <blendergit@gmail.com>2020-03-14 18:26:56 +0300
commita816a067ede6c8df3fc3a32bba2370a0ef179061 (patch)
tree7b71fd5dcbe76ac6e593a4641f7fba3999bf210e
parentb7160f2f0a601988b64be7c205ee9e26ab1da112 (diff)
GPencil: Change Select Vertex Color to similar selection
Now, instead to use the Brush color as selection patron, now it uses any previous selected color.
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c109
1 files changed, 91 insertions, 18 deletions
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 43e13e88b9c..ee9e91d0e81 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -1655,6 +1655,49 @@ void GPENCIL_OT_select(wmOperatorType *ot)
}
/* Select by Vertex Color. */
+/* Helper to create a hash of colors. */
+static void gpencil_selected_hue_table(bContext *C,
+ Object *ob,
+ const int threshold,
+ GHash *hue_table)
+{
+ const float range = pow(10, 7 - threshold);
+ float hsv[3];
+
+ /* Extract all colors. */
+ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ continue;
+ }
+ if ((gps->flag & GP_STROKE_SELECT) == 0) {
+ continue;
+ }
+
+ /* Read all points to get all colors selected. */
+ bGPDspoint *pt;
+ int i;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (((pt->flag & GP_SPOINT_SELECT) == 0) || (pt->vert_color[3] == 0.0f)) {
+ continue;
+ }
+ /* Round Hue value. */
+ rgb_to_hsv_compat_v(pt->vert_color, hsv);
+ uint key = truncf(hsv[0] * range);
+ if (!BLI_ghash_haskey(hue_table, POINTER_FROM_INT(key))) {
+ BLI_ghash_insert(hue_table, POINTER_FROM_INT(key), POINTER_FROM_INT(key));
+ }
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+}
+
static bool gpencil_select_vertex_color_poll(bContext *C)
{
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -1680,25 +1723,28 @@ static bool gpencil_select_vertex_color_poll(bContext *C)
static int gpencil_select_vertex_color_exec(bContext *C, wmOperator *op)
{
- const float threshold = RNA_float_get(op->ptr, "threshold");
- const bool keep = RNA_boolean_get(op->ptr, "keep");
-
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
+
+ const float threshold = RNA_int_get(op->ptr, "threshold");
+ const bool keep = RNA_boolean_get(op->ptr, "keep");
+ const int selectmode = gpencil_select_mode_from_vertex(ts->gpencil_selectmode_vertex);
bGPdata *gpd = (bGPdata *)ob->data;
- if (!GPENCIL_VERTEX_MODE(gpd)) {
- return OPERATOR_CANCELLED;
- }
+ const float range = pow(10, 7 - threshold);
- Paint *paint = &ts->gp_vertexpaint->paint;
- Brush *brush = paint->brush;
bool done = false;
- float hsv_brush[3], hsv_stroke[3], linear_color[3];
- srgb_to_linearrgb_v3_v3(linear_color, brush->rgb);
- rgb_to_hsv_compat_v(linear_color, hsv_brush);
+ /* Create a hash table with all selected colors. */
+ GHash *hue_table = BLI_ghash_int_new(__func__);
+ gpencil_selected_hue_table(C, ob, threshold, hue_table);
+ if (BLI_ghash_len(hue_table) == 0) {
+ BKE_report(op->reports, RPT_ERROR, "Select before some Vertex to use as a filter color");
+ BLI_ghash_free(hue_table, NULL, NULL);
- /* Select any visible stroke that uses this color */
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Select any visible stroke that uses any of these colors. */
CTX_DATA_BEGIN (C, bGPDstroke *, gps, editable_gpencil_strokes) {
bGPDspoint *pt;
int i;
@@ -1715,13 +1761,17 @@ static int gpencil_select_vertex_color_exec(bContext *C, wmOperator *op)
pt->flag &= ~GP_SPOINT_SELECT;
}
- if (pt->vert_color[3] < 0.03f) {
+ if (pt->vert_color[3] == 0.0f) {
continue;
}
- rgb_to_hsv_compat_v(pt->vert_color, hsv_stroke);
- /* Only check Hue to get full value and saturation ranges. */
- if (compare_ff(hsv_stroke[0], hsv_brush[0], threshold)) {
+ /* Only check Hue to get value and saturation full ranges. */
+ float hsv[3];
+ /* Round Hue value. */
+ rgb_to_hsv_compat_v(pt->vert_color, hsv);
+ uint key = truncf(hsv[0] * range);
+
+ if (BLI_ghash_haskey(hue_table, POINTER_FROM_INT(key))) {
pt->flag |= GP_SPOINT_SELECT;
gps_selected = true;
}
@@ -1730,6 +1780,16 @@ static int gpencil_select_vertex_color_exec(bContext *C, wmOperator *op)
if (gps_selected) {
gps->flag |= GP_STROKE_SELECT;
done = true;
+
+ /* Extend stroke selection. */
+ if (selectmode == GP_SELECTMODE_STROKE) {
+ bGPDspoint *pt1 = NULL;
+ int i;
+
+ for (i = 0, pt1 = gps->points; i < gps->totpoints; i++, pt1++) {
+ pt1->flag |= GP_SPOINT_SELECT;
+ }
+ }
}
}
CTX_DATA_END;
@@ -1745,6 +1805,11 @@ static int gpencil_select_vertex_color_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);
}
+ /* Free memory. */
+ if (hue_table != NULL) {
+ BLI_ghash_free(hue_table, NULL, NULL);
+ }
+
return OPERATOR_FINISHED;
}
@@ -1755,7 +1820,7 @@ void GPENCIL_OT_select_vertex_color(wmOperatorType *ot)
/* identifiers */
ot->name = "Select Vertex Color";
ot->idname = "GPENCIL_OT_select_vertex_color";
- ot->description = "Select all strokes with same vertex color";
+ ot->description = "Select all points with similar vertex color of current selected";
/* callbacks */
ot->exec = gpencil_select_vertex_color_exec;
@@ -1765,7 +1830,15 @@ void GPENCIL_OT_select_vertex_color(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- prop = RNA_def_float(ot->srna, "threshold", 0.01f, 0.0f, 1.0f, "Threshold", "", 0.0f, 1.0f);
+ prop = RNA_def_int(ot->srna,
+ "threshold",
+ 0,
+ 0,
+ 6,
+ "Threshold",
+ "Tolerance of the selection. Higher values select a wider range of similar colors",
+ 0,
+ 6);
/* avoid re-using last var */
RNA_def_property_flag(prop, PROP_SKIP_SAVE);