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:
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c43
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c47
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c43
-rw-r--r--source/blender/editors/include/ED_gpencil.h4
4 files changed, 87 insertions, 50 deletions
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 7accf48832a..c41b2993a80 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -68,45 +68,6 @@
/** \name Shared Utilities
* \{ */
-/* Check if mouse inside stroke. */
-static bool gpencil_point_inside_stroke(bGPDstroke *gps,
- GP_SpaceConversion *gsc,
- int mouse[2],
- const float diff_mat[4][4])
-{
- bool hit = false;
- if (gps->totpoints == 0) {
- return hit;
- }
-
- int(*mcoords)[2] = NULL;
- int len = gps->totpoints;
- mcoords = MEM_mallocN(sizeof(int) * 2 * len, __func__);
-
- /* Convert stroke to 2D array of points. */
- bGPDspoint *pt;
- int i;
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- bGPDspoint pt2;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy(gsc, gps, &pt2, &mcoords[i][0], &mcoords[i][1]);
- }
-
- /* Compute boundbox of lasso (for faster testing later). */
- rcti rect;
- BLI_lasso_boundbox(&rect, mcoords, len);
-
- /* Test if point inside stroke. */
- hit = ((!ELEM(V2D_IS_CLIPPED, mouse[0], mouse[1])) &&
- BLI_rcti_isect_pt(&rect, mouse[0], mouse[1]) &&
- BLI_lasso_is_point_inside(mcoords, len, mouse[0], mouse[1], INT_MAX));
-
- /* Free memory. */
- MEM_SAFE_FREE(mcoords);
-
- return hit;
-}
-
/* Convert sculpt mask mode to Select mode */
static int gpencil_select_mode_from_sculpt(eGP_Sculpt_SelectMaskFlag mode)
{
@@ -1264,7 +1225,7 @@ static int gpencil_generic_select_exec(
mval[0] = (box.xmax + box.xmin) / 2;
mval[1] = (box.ymax + box.ymin) / 2;
- whole = gpencil_point_inside_stroke(gps_active, &gsc, mval, gpstroke_iter.diff_mat);
+ whole = ED_gpencil_stroke_point_is_inside(gps_active, &gsc, mval, gpstroke_iter.diff_mat);
}
/* if stroke mode expand selection. */
@@ -1565,7 +1526,7 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
if ((gp_style->flag & GP_MATERIAL_FILL_SHOW) == 0) {
continue;
}
- bool hit_fill = gpencil_point_inside_stroke(gps, &gsc, mval, gpstroke_iter.diff_mat);
+ bool hit_fill = ED_gpencil_stroke_point_is_inside(gps, &gsc, mval, gpstroke_iter.diff_mat);
if (hit_fill) {
hit_stroke = gps_active;
hit_point = &gps_active->points[0];
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 1962eba5017..876fa7c9874 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -31,6 +31,7 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
#include "BLI_hash.h"
+#include "BLI_lasso_2d.h"
#include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_utildefines.h"
@@ -2799,3 +2800,49 @@ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc,
/* Check collision between both rectangles. */
return BLI_rcti_isect(&rect_stroke, &rect_mouse, NULL);
}
+
+/**
+ * Check if a point is inside of the stroke
+ * \param gps: Stroke to check
+ * \param gsc: SpaceConversion data
+ * \param mouse: Mouse position
+ * \param diff_mat: View matrix
+ * \return True if the point is inside
+ */
+bool ED_gpencil_stroke_point_is_inside(bGPDstroke *gps,
+ GP_SpaceConversion *gsc,
+ int mouse[2],
+ const float diff_mat[4][4])
+{
+ bool hit = false;
+ if (gps->totpoints == 0) {
+ return hit;
+ }
+
+ int(*mcoords)[2] = NULL;
+ int len = gps->totpoints;
+ mcoords = MEM_mallocN(sizeof(int) * 2 * len, __func__);
+
+ /* Convert stroke to 2D array of points. */
+ bGPDspoint *pt;
+ int i;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ bGPDspoint pt2;
+ gp_point_to_parent_space(pt, diff_mat, &pt2);
+ gp_point_to_xy(gsc, gps, &pt2, &mcoords[i][0], &mcoords[i][1]);
+ }
+
+ /* Compute boundbox of lasso (for faster testing later). */
+ rcti rect;
+ BLI_lasso_boundbox(&rect, mcoords, len);
+
+ /* Test if point inside stroke. */
+ hit = ((!ELEM(V2D_IS_CLIPPED, mouse[0], mouse[1])) &&
+ BLI_rcti_isect_pt(&rect, mouse[0], mouse[1]) &&
+ BLI_lasso_is_point_inside(mcoords, len, mouse[0], mouse[1], INT_MAX));
+
+ /* Free memory. */
+ MEM_SAFE_FREE(mcoords);
+
+ return hit;
+}
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index 10867bd1e0d..581a5d977c2 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -36,6 +36,7 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
+#include "BKE_material.h"
#include "BKE_report.h"
#include "WM_api.h"
@@ -433,10 +434,9 @@ static bool brush_tint_apply(tGP_BrushVertexpaintData *gso,
CLAMP(inf, 0.0f, 1.0f);
CLAMP(inf_fill, 0.0f, 1.0f);
- bGPDspoint *pt = &gps->points[pt_index];
-
/* Apply color to Stroke point. */
- if (GPENCIL_TINT_VERTEX_COLOR_STROKE(brush)) {
+ if (GPENCIL_TINT_VERTEX_COLOR_STROKE(brush) && (pt_index > -1)) {
+ bGPDspoint *pt = &gps->points[pt_index];
if (brush_invert_check(gso)) {
pt->vert_color[3] -= inf;
CLAMP_MIN(pt->vert_color[3], 0.0f);
@@ -813,15 +813,18 @@ static void gp_save_selected_point(tGP_BrushVertexpaintData *gso,
selected = &gso->pbuffer[gso->pbuffer_used];
selected->gps = gps;
selected->pt_index = index;
- copy_v2_v2_int(selected->pc, pc);
- copy_v4_v4(selected->color, pt->vert_color);
-
+ /* Check the index is not a special case for fill. */
+ if (index > -1) {
+ copy_v2_v2_int(selected->pc, pc);
+ copy_v4_v4(selected->color, pt->vert_color);
+ }
gso->pbuffer_used++;
}
/* Select points in this stroke and add to an array to be used later. */
static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
bGPDstroke *gps,
+ const char tool,
const float diff_mat[4][4])
{
GP_SpaceConversion *gsc = &gso->gsc;
@@ -869,6 +872,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
/* Loop over the points in the stroke, checking for intersections
* - an intersection means that we touched the stroke
*/
+ bool hit = false;
for (i = 0; (i + 1) < gps->totpoints; i++) {
/* Get points to work with */
pt1 = gps->points + i;
@@ -904,6 +908,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
if (pt_active != NULL) {
+ hit = true;
gp_save_selected_point(gso, gps_active, index, pc1);
}
@@ -920,6 +925,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i + 1;
if (pt_active != NULL) {
+ hit = true;
gp_save_selected_point(gso, gps_active, index, pc2);
include_last = false;
}
@@ -938,6 +944,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
if (pt_active != NULL) {
+ hit = true;
gp_save_selected_point(gso, gps_active, index, pc1);
include_last = false;
@@ -945,6 +952,24 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
}
}
}
+
+ /* If nothing hit, check if the mouse is inside any filled stroke. */
+ if ((!hit) && (ELEM(tool, GPAINT_TOOL_TINT, GPVERTEX_TOOL_DRAW))) {
+ MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(gso->object,
+ gps_active->mat_nr + 1);
+ if (gp_style->flag & GP_MATERIAL_FILL_SHOW) {
+ int mval[2];
+ round_v2i_v2fl(mval, gso->mval);
+ bool hit_fill = ED_gpencil_stroke_point_is_inside(gps_active, gsc, mval, diff_mat);
+ if (hit_fill) {
+ /* Need repeat the effect because if we don't do that the tint process
+ * is very slow. */
+ for (int repeat = 0; repeat < 50; repeat++) {
+ gp_save_selected_point(gso, gps_active, -1, NULL);
+ }
+ }
+ }
+ }
}
}
@@ -956,8 +981,8 @@ static bool gp_vertexpaint_brush_do_frame(bContext *C,
const float diff_mat[4][4])
{
Object *ob = CTX_data_active_object(C);
- char tool = ob->mode == OB_MODE_VERTEX_GPENCIL ? gso->brush->gpencil_vertex_tool :
- gso->brush->gpencil_tool;
+ const char tool = ob->mode == OB_MODE_VERTEX_GPENCIL ? gso->brush->gpencil_vertex_tool :
+ gso->brush->gpencil_tool;
const int radius = (gso->brush->flag & GP_BRUSH_USE_PRESSURE) ?
gso->brush->size * gso->pressure :
gso->brush->size;
@@ -980,7 +1005,7 @@ static bool gp_vertexpaint_brush_do_frame(bContext *C,
}
/* Check points below the brush. */
- gp_vertexpaint_select_stroke(gso, gps, diff_mat);
+ gp_vertexpaint_select_stroke(gso, gps, tool, diff_mat);
}
/* For Average tool, need calculate the average resulting color from all colors
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 58364e69679..0c228fc962b 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -317,6 +317,10 @@ bool ED_gpencil_stroke_check_collision(struct GP_SpaceConversion *gsc,
float mouse[2],
const int radius,
const float diff_mat[4][4]);
+bool ED_gpencil_stroke_point_is_inside(struct bGPDstroke *gps,
+ struct GP_SpaceConversion *gsc,
+ int mouse[2],
+ const float diff_mat[4][4]);
#ifdef __cplusplus
}