diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/editors/gpencil/gpencil_merge.c | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/editors/gpencil/gpencil_merge.c')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_merge.c | 909 |
1 files changed, 455 insertions, 454 deletions
diff --git a/source/blender/editors/gpencil/gpencil_merge.c b/source/blender/editors/gpencil/gpencil_merge.c index 10bf45a9e2f..48c761919e5 100644 --- a/source/blender/editors/gpencil/gpencil_merge.c +++ b/source/blender/editors/gpencil/gpencil_merge.c @@ -54,144 +54,144 @@ #include "gpencil_intern.h" typedef struct tGPencilPointCache { - float factor; /* value to sort */ - bGPDstroke *gps; - float x, y, z; - float pressure; - float strength; + float factor; /* value to sort */ + bGPDstroke *gps; + float x, y, z; + float pressure; + float strength; } tGPencilPointCache; /* helper function to sort points */ static int gpencil_sort_points(const void *a1, const void *a2) { - const tGPencilPointCache *ps1 = a1, *ps2 = a2; + const tGPencilPointCache *ps1 = a1, *ps2 = a2; - if (ps1->factor < ps2->factor) return -1; - else if (ps1->factor > ps2->factor) return 1; + if (ps1->factor < ps2->factor) + return -1; + else if (ps1->factor > ps2->factor) + return 1; - return 0; + return 0; } -static void gpencil_insert_points_to_stroke( - bGPDstroke *gps, tGPencilPointCache *points_array, int totpoints) +static void gpencil_insert_points_to_stroke(bGPDstroke *gps, + tGPencilPointCache *points_array, + int totpoints) { - tGPencilPointCache *point_elem = NULL; - - for (int i = 0; i < totpoints; i++) { - point_elem = &points_array[i]; - bGPDspoint *pt_dst = &gps->points[i]; - - copy_v3_v3(&pt_dst->x, &point_elem->x); - pt_dst->pressure = point_elem->pressure; - pt_dst->strength = point_elem->strength; - pt_dst->uv_fac = 1.0f; - pt_dst->uv_rot = 0; - pt_dst->flag |= GP_SPOINT_SELECT; - } - + tGPencilPointCache *point_elem = NULL; + + for (int i = 0; i < totpoints; i++) { + point_elem = &points_array[i]; + bGPDspoint *pt_dst = &gps->points[i]; + + copy_v3_v3(&pt_dst->x, &point_elem->x); + pt_dst->pressure = point_elem->pressure; + pt_dst->strength = point_elem->strength; + pt_dst->uv_fac = 1.0f; + pt_dst->uv_rot = 0; + pt_dst->flag |= GP_SPOINT_SELECT; + } } static bGPDstroke *gpencil_prepare_stroke(bContext *C, wmOperator *op, int totpoints) { - ToolSettings *ts = CTX_data_tool_settings(C); - Depsgraph *depsgraph = CTX_data_depsgraph(C); - Object *ob = CTX_data_active_object(C); - bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); - - int cfra_eval = (int)DEG_get_ctime(depsgraph); - - const bool back = RNA_boolean_get(op->ptr, "back"); - const bool additive = RNA_boolean_get(op->ptr, "additive"); - const bool cyclic = RNA_boolean_get(op->ptr, "cyclic"); - - Paint *paint = &ts->gp_paint->paint; - /* if not exist, create a new one */ - if (paint->brush == NULL) { - /* create new brushes */ - BKE_brush_gpencil_presets(C); - } - Brush *brush = paint->brush; - - /* frame */ - short add_frame_mode; - if (additive) { - add_frame_mode = GP_GETFRAME_ADD_COPY; - } - else { - add_frame_mode = GP_GETFRAME_ADD_NEW; - } - bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, add_frame_mode); - - /* stroke */ - bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); - gps->totpoints = totpoints; - gps->inittime = 0.0f; - gps->thickness = brush->size; - gps->gradient_f = brush->gpencil_settings->gradient_f; - copy_v2_v2(gps->gradient_s, brush->gpencil_settings->gradient_s); - gps->flag |= GP_STROKE_SELECT; - gps->flag |= GP_STROKE_3DSPACE; - gps->mat_nr = ob->actcol - 1; - - /* allocate memory for points */ - gps->points = MEM_callocN(sizeof(bGPDspoint) * totpoints, "gp_stroke_points"); - /* initialize triangle memory to dummy data */ - gps->tot_triangles = 0; - gps->triangles = NULL; - gps->flag |= GP_STROKE_RECALC_GEOMETRY; - - if (cyclic) { - gps->flag |= GP_STROKE_CYCLIC; - } - - /* add new stroke to frame */ - if (back) { - BLI_addhead(&gpf->strokes, gps); - } - else { - BLI_addtail(&gpf->strokes, gps); - } - - return gps; + ToolSettings *ts = CTX_data_tool_settings(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + Object *ob = CTX_data_active_object(C); + bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); + + int cfra_eval = (int)DEG_get_ctime(depsgraph); + + const bool back = RNA_boolean_get(op->ptr, "back"); + const bool additive = RNA_boolean_get(op->ptr, "additive"); + const bool cyclic = RNA_boolean_get(op->ptr, "cyclic"); + + Paint *paint = &ts->gp_paint->paint; + /* if not exist, create a new one */ + if (paint->brush == NULL) { + /* create new brushes */ + BKE_brush_gpencil_presets(C); + } + Brush *brush = paint->brush; + + /* frame */ + short add_frame_mode; + if (additive) { + add_frame_mode = GP_GETFRAME_ADD_COPY; + } + else { + add_frame_mode = GP_GETFRAME_ADD_NEW; + } + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, add_frame_mode); + + /* stroke */ + bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); + gps->totpoints = totpoints; + gps->inittime = 0.0f; + gps->thickness = brush->size; + gps->gradient_f = brush->gpencil_settings->gradient_f; + copy_v2_v2(gps->gradient_s, brush->gpencil_settings->gradient_s); + gps->flag |= GP_STROKE_SELECT; + gps->flag |= GP_STROKE_3DSPACE; + gps->mat_nr = ob->actcol - 1; + + /* allocate memory for points */ + gps->points = MEM_callocN(sizeof(bGPDspoint) * totpoints, "gp_stroke_points"); + /* initialize triangle memory to dummy data */ + gps->tot_triangles = 0; + gps->triangles = NULL; + gps->flag |= GP_STROKE_RECALC_GEOMETRY; + + if (cyclic) { + gps->flag |= GP_STROKE_CYCLIC; + } + + /* add new stroke to frame */ + if (back) { + BLI_addhead(&gpf->strokes, gps); + } + else { + BLI_addtail(&gpf->strokes, gps); + } + + return gps; } static void gpencil_get_elements_len(bContext *C, int *totstrokes, int *totpoints) { - bGPDspoint *pt; - int i; - - /* count number of strokes and selected points */ - CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) - { - if (gps->flag & GP_STROKE_SELECT) { - *totstrokes += 1; - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) { - *totpoints += 1; - } - } - } - } - CTX_DATA_END; + bGPDspoint *pt; + int i; + + /* count number of strokes and selected points */ + CTX_DATA_BEGIN (C, bGPDstroke *, gps, editable_gpencil_strokes) { + if (gps->flag & GP_STROKE_SELECT) { + *totstrokes += 1; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + *totpoints += 1; + } + } + } + } + CTX_DATA_END; } static void gpencil_dissolve_points(bContext *C) { - bGPDstroke *gps, *gpsn; - - CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) - { - bGPDframe *gpf = gpl->actframe; - if (gpf == NULL) { - continue; - } - - for (gps = gpf->strokes.first; gps; gps = gpsn) { - gpsn = gps->next; - gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_TAG, false, 0); - } - } - CTX_DATA_END; + bGPDstroke *gps, *gpsn; + + CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { + bGPDframe *gpf = gpl->actframe; + if (gpf == NULL) { + continue; + } + + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_TAG, false, 0); + } + } + CTX_DATA_END; } /* Calc a factor of each selected point and fill an array with all the data. @@ -201,367 +201,368 @@ static void gpencil_dissolve_points(bContext *C) * * All the data is saved to be sorted and used later. */ -static void gpencil_calc_points_factor( - bContext *C, const int mode, int totpoints, - const bool clear_point, const bool clear_stroke, - tGPencilPointCache *src_array) +static void gpencil_calc_points_factor(bContext *C, + const int mode, + int totpoints, + const bool clear_point, + const bool clear_stroke, + tGPencilPointCache *src_array) { - bGPDspoint *pt; - int i; - int idx = 0; - - /* create selected point array an fill it */ - bGPDstroke **gps_array = MEM_callocN(sizeof(bGPDstroke *) * totpoints, __func__); - bGPDspoint *pt_array = MEM_callocN(sizeof(bGPDspoint) * totpoints, __func__); - - CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) - { - bGPDframe *gpf = gpl->actframe; - if (gpf == NULL) { - continue; - } - for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { - if (gps->flag & GP_STROKE_SELECT) { - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (clear_stroke) { - pt->flag |= GP_SPOINT_TAG; - } - else { - pt->flag &= ~GP_SPOINT_TAG; - } - - if (pt->flag & GP_SPOINT_SELECT) { - bGPDspoint *pt2 = &pt_array[idx]; - copy_v3_v3(&pt2->x, &pt->x); - pt2->pressure = pt->pressure; - pt2->strength = pt->strength; - pt->flag &= ~GP_SPOINT_SELECT; - if (clear_point) { - pt->flag |= GP_SPOINT_TAG; - } - - /* save stroke */ - gps_array[idx] = gps; - - idx++; - } - } - gps->flag &= ~GP_STROKE_SELECT; - } - } - } - CTX_DATA_END; - - /* project in 2d plane */ - int direction = 0; - float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, "GP Stroke temp 2d points"); - BKE_gpencil_stroke_2d_flat(pt_array, totpoints, points2d, &direction); - - /* calc center */ - float center[2] = { 0.0f, 0.0f }; - for (i = 0; i < totpoints; i++) { - center[0] += points2d[i][0]; - center[1] += points2d[i][1]; - } - mul_v2_fl(center, 1.0f / totpoints); - - /* calc angle and distance to center for each point */ - const float axis[2] = { 1.0f, 0.0f }; - float v1[3]; - for (i = 0; i < totpoints; i++) { - float ln = len_v2v2(center, points2d[i]); - sub_v2_v2v2(v1, points2d[i], center); - float angle = angle_signed_v2v2(axis, v1); - if (angle < 0.0f) { - angle = fabsf(angle); - } - else { - angle = (M_PI * 2.0) - angle; - } - tGPencilPointCache *sort_pt = &src_array[i]; - bGPDspoint *pt2 = &pt_array[i]; - - copy_v3_v3(&sort_pt->x, &pt2->x); - sort_pt->pressure = pt2->pressure; - sort_pt->strength = pt2->strength; - - sort_pt->gps = gps_array[i]; - - if (mode == GP_MERGE_STROKE) { - sort_pt->factor = angle; - } - else { - sort_pt->factor = (angle * 100000.0f) + ln; - } - } - MEM_SAFE_FREE(points2d); - MEM_SAFE_FREE(gps_array); - MEM_SAFE_FREE(pt_array); + bGPDspoint *pt; + int i; + int idx = 0; + + /* create selected point array an fill it */ + bGPDstroke **gps_array = MEM_callocN(sizeof(bGPDstroke *) * totpoints, __func__); + bGPDspoint *pt_array = MEM_callocN(sizeof(bGPDspoint) * totpoints, __func__); + + CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { + bGPDframe *gpf = gpl->actframe; + if (gpf == NULL) { + continue; + } + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + if (gps->flag & GP_STROKE_SELECT) { + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (clear_stroke) { + pt->flag |= GP_SPOINT_TAG; + } + else { + pt->flag &= ~GP_SPOINT_TAG; + } + + if (pt->flag & GP_SPOINT_SELECT) { + bGPDspoint *pt2 = &pt_array[idx]; + copy_v3_v3(&pt2->x, &pt->x); + pt2->pressure = pt->pressure; + pt2->strength = pt->strength; + pt->flag &= ~GP_SPOINT_SELECT; + if (clear_point) { + pt->flag |= GP_SPOINT_TAG; + } + + /* save stroke */ + gps_array[idx] = gps; + + idx++; + } + } + gps->flag &= ~GP_STROKE_SELECT; + } + } + } + CTX_DATA_END; + + /* project in 2d plane */ + int direction = 0; + float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, "GP Stroke temp 2d points"); + BKE_gpencil_stroke_2d_flat(pt_array, totpoints, points2d, &direction); + + /* calc center */ + float center[2] = {0.0f, 0.0f}; + for (i = 0; i < totpoints; i++) { + center[0] += points2d[i][0]; + center[1] += points2d[i][1]; + } + mul_v2_fl(center, 1.0f / totpoints); + + /* calc angle and distance to center for each point */ + const float axis[2] = {1.0f, 0.0f}; + float v1[3]; + for (i = 0; i < totpoints; i++) { + float ln = len_v2v2(center, points2d[i]); + sub_v2_v2v2(v1, points2d[i], center); + float angle = angle_signed_v2v2(axis, v1); + if (angle < 0.0f) { + angle = fabsf(angle); + } + else { + angle = (M_PI * 2.0) - angle; + } + tGPencilPointCache *sort_pt = &src_array[i]; + bGPDspoint *pt2 = &pt_array[i]; + + copy_v3_v3(&sort_pt->x, &pt2->x); + sort_pt->pressure = pt2->pressure; + sort_pt->strength = pt2->strength; + + sort_pt->gps = gps_array[i]; + + if (mode == GP_MERGE_STROKE) { + sort_pt->factor = angle; + } + else { + sort_pt->factor = (angle * 100000.0f) + ln; + } + } + MEM_SAFE_FREE(points2d); + MEM_SAFE_FREE(gps_array); + MEM_SAFE_FREE(pt_array); } /* insert a group of points in destination array */ -static int gpencil_insert_to_array( - tGPencilPointCache *src_array, tGPencilPointCache *dst_array, int totpoints, - bGPDstroke *gps_filter, bool reverse, int last) +static int gpencil_insert_to_array(tGPencilPointCache *src_array, + tGPencilPointCache *dst_array, + int totpoints, + bGPDstroke *gps_filter, + bool reverse, + int last) { - tGPencilPointCache *src_elem = NULL; - tGPencilPointCache *dst_elem = NULL; - int idx = 0; - - for (int i = 0; i < totpoints; i++) { - if (!reverse) { - idx = i; - } - else { - idx = totpoints - i - 1; - } - src_elem = &src_array[idx]; - /* check if all points or only a stroke */ - if ((gps_filter != NULL) && (gps_filter != src_elem->gps)) { - continue; - } - - dst_elem = &dst_array[last]; - last++; - - copy_v3_v3(&dst_elem->x, &src_elem->x); - dst_elem->gps = src_elem->gps; - dst_elem->pressure = src_elem->pressure; - dst_elem->strength = src_elem->strength; - dst_elem->factor = src_elem->factor; - } - - return last; + tGPencilPointCache *src_elem = NULL; + tGPencilPointCache *dst_elem = NULL; + int idx = 0; + + for (int i = 0; i < totpoints; i++) { + if (!reverse) { + idx = i; + } + else { + idx = totpoints - i - 1; + } + src_elem = &src_array[idx]; + /* check if all points or only a stroke */ + if ((gps_filter != NULL) && (gps_filter != src_elem->gps)) { + continue; + } + + dst_elem = &dst_array[last]; + last++; + + copy_v3_v3(&dst_elem->x, &src_elem->x); + dst_elem->gps = src_elem->gps; + dst_elem->pressure = src_elem->pressure; + dst_elem->strength = src_elem->strength; + dst_elem->factor = src_elem->factor; + } + + return last; } /* get first and last point location */ static void gpencil_get_extremes( - tGPencilPointCache *src_array, int totpoints, - bGPDstroke *gps_filter, float *start, float *end) + tGPencilPointCache *src_array, int totpoints, bGPDstroke *gps_filter, float *start, float *end) { - tGPencilPointCache *array_pt = NULL; - int i; - - /* find first point */ - for (i = 0; i < totpoints; i++) { - array_pt = &src_array[i]; - if (gps_filter == array_pt->gps) { - copy_v3_v3(start, &array_pt->x); - break; - } - } - /* find last point */ - for (i = totpoints - 1; i >= 0; i--) { - array_pt = &src_array[i]; - if (gps_filter == array_pt->gps) { - copy_v3_v3(end, &array_pt->x); - break; - } - } + tGPencilPointCache *array_pt = NULL; + int i; + + /* find first point */ + for (i = 0; i < totpoints; i++) { + array_pt = &src_array[i]; + if (gps_filter == array_pt->gps) { + copy_v3_v3(start, &array_pt->x); + break; + } + } + /* find last point */ + for (i = totpoints - 1; i >= 0; i--) { + array_pt = &src_array[i]; + if (gps_filter == array_pt->gps) { + copy_v3_v3(end, &array_pt->x); + break; + } + } } -static int gpencil_analyze_strokes( - tGPencilPointCache *src_array, int totstrokes, int totpoints, - tGPencilPointCache *dst_array) +static int gpencil_analyze_strokes(tGPencilPointCache *src_array, + int totstrokes, + int totpoints, + tGPencilPointCache *dst_array) { - int i; - int last = 0; - GHash *all_strokes = BLI_ghash_ptr_new(__func__); - /* add first stroke to array */ - tGPencilPointCache *sort_pt = &src_array[0]; - bGPDstroke *gps = sort_pt->gps; - last = gpencil_insert_to_array(src_array, dst_array, totpoints, gps, false, last); - float start[3]; - float end[3]; - float end_prv[3]; - gpencil_get_extremes(src_array, totpoints, gps, start, end); - copy_v3_v3(end_prv, end); - BLI_ghash_insert(all_strokes, sort_pt->gps, sort_pt->gps); - - /* look for near stroke */ - bool loop = (bool)(totstrokes > 1); - while (loop) { - bGPDstroke *gps_next = NULL; - GHash *strokes = BLI_ghash_ptr_new(__func__); - float dist_start = 0.0f; - float dist_end = 0.0f; - float dist = FLT_MAX; - bool reverse = false; - - for (i = 0; i < totpoints; i++) { - sort_pt = &src_array[i]; - /* avoid dups */ - if (BLI_ghash_haskey(all_strokes, sort_pt->gps)) { - continue; - } - if (!BLI_ghash_haskey(strokes, sort_pt->gps)) { - gpencil_get_extremes(src_array, totpoints, sort_pt->gps, start, end); - /* distances to previous end */ - dist_start = len_v3v3(end_prv, start); - dist_end = len_v3v3(end_prv, end); - - if (dist > dist_start) { - gps_next = sort_pt->gps; - dist = dist_start; - reverse = false; - } - if (dist > dist_end) { - gps_next = sort_pt->gps; - dist = dist_end; - reverse = true; - } - BLI_ghash_insert(strokes, sort_pt->gps, sort_pt->gps); - } - } - BLI_ghash_free(strokes, NULL, NULL); - - /* add the stroke to array */ - if (gps->next != NULL) { - BLI_ghash_insert(all_strokes, gps_next, gps_next); - last = gpencil_insert_to_array(src_array, dst_array, totpoints, gps_next, reverse, last); - /* replace last end */ - sort_pt = &dst_array[last - 1]; - copy_v3_v3(end_prv, &sort_pt->x); - } - - /* loop exit */ - if (last >= totpoints) { - loop = false; - } - } - - BLI_ghash_free(all_strokes, NULL, NULL); - return last; + int i; + int last = 0; + GHash *all_strokes = BLI_ghash_ptr_new(__func__); + /* add first stroke to array */ + tGPencilPointCache *sort_pt = &src_array[0]; + bGPDstroke *gps = sort_pt->gps; + last = gpencil_insert_to_array(src_array, dst_array, totpoints, gps, false, last); + float start[3]; + float end[3]; + float end_prv[3]; + gpencil_get_extremes(src_array, totpoints, gps, start, end); + copy_v3_v3(end_prv, end); + BLI_ghash_insert(all_strokes, sort_pt->gps, sort_pt->gps); + + /* look for near stroke */ + bool loop = (bool)(totstrokes > 1); + while (loop) { + bGPDstroke *gps_next = NULL; + GHash *strokes = BLI_ghash_ptr_new(__func__); + float dist_start = 0.0f; + float dist_end = 0.0f; + float dist = FLT_MAX; + bool reverse = false; + + for (i = 0; i < totpoints; i++) { + sort_pt = &src_array[i]; + /* avoid dups */ + if (BLI_ghash_haskey(all_strokes, sort_pt->gps)) { + continue; + } + if (!BLI_ghash_haskey(strokes, sort_pt->gps)) { + gpencil_get_extremes(src_array, totpoints, sort_pt->gps, start, end); + /* distances to previous end */ + dist_start = len_v3v3(end_prv, start); + dist_end = len_v3v3(end_prv, end); + + if (dist > dist_start) { + gps_next = sort_pt->gps; + dist = dist_start; + reverse = false; + } + if (dist > dist_end) { + gps_next = sort_pt->gps; + dist = dist_end; + reverse = true; + } + BLI_ghash_insert(strokes, sort_pt->gps, sort_pt->gps); + } + } + BLI_ghash_free(strokes, NULL, NULL); + + /* add the stroke to array */ + if (gps->next != NULL) { + BLI_ghash_insert(all_strokes, gps_next, gps_next); + last = gpencil_insert_to_array(src_array, dst_array, totpoints, gps_next, reverse, last); + /* replace last end */ + sort_pt = &dst_array[last - 1]; + copy_v3_v3(end_prv, &sort_pt->x); + } + + /* loop exit */ + if (last >= totpoints) { + loop = false; + } + } + + BLI_ghash_free(all_strokes, NULL, NULL); + return last; } static bool gp_strokes_merge_poll(bContext *C) { - /* only supported with grease pencil objects */ - Object *ob = CTX_data_active_object(C); - if ((ob == NULL) || (ob->type != OB_GPENCIL)) { - return false; - } - - /* check material */ - Material *ma = NULL; - ma = give_current_material(ob, ob->actcol); - if ((ma == NULL) || (ma->gp_style == NULL)) { - return false; - } - - /* check hidden or locked materials */ - MaterialGPencilStyle *gp_style = ma->gp_style; - if ((gp_style->flag & GP_STYLE_COLOR_HIDE) || - (gp_style->flag & GP_STYLE_COLOR_LOCKED)) - { - return false; - } - - /* check layer */ - bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); - if ((gpl == NULL) || - (gpl->flag & GP_LAYER_LOCKED) || - (gpl->flag & GP_LAYER_HIDE)) - { - return false; - } - - /* NOTE: this is a bit slower, but is the most accurate... */ - return (CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0) && ED_operator_view3d_active(C); + /* only supported with grease pencil objects */ + Object *ob = CTX_data_active_object(C); + if ((ob == NULL) || (ob->type != OB_GPENCIL)) { + return false; + } + + /* check material */ + Material *ma = NULL; + ma = give_current_material(ob, ob->actcol); + if ((ma == NULL) || (ma->gp_style == NULL)) { + return false; + } + + /* check hidden or locked materials */ + MaterialGPencilStyle *gp_style = ma->gp_style; + if ((gp_style->flag & GP_STYLE_COLOR_HIDE) || (gp_style->flag & GP_STYLE_COLOR_LOCKED)) { + return false; + } + + /* check layer */ + bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); + if ((gpl == NULL) || (gpl->flag & GP_LAYER_LOCKED) || (gpl->flag & GP_LAYER_HIDE)) { + return false; + } + + /* NOTE: this is a bit slower, but is the most accurate... */ + return (CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0) && ED_operator_view3d_active(C); } static int gp_stroke_merge_exec(bContext *C, wmOperator *op) { - const int mode = RNA_enum_get(op->ptr, "mode"); - const bool clear_point = RNA_boolean_get(op->ptr, "clear_point"); - const bool clear_stroke = RNA_boolean_get(op->ptr, "clear_stroke"); - - Object *ob = CTX_data_active_object(C); - /* sanity checks */ - if (!ob || ob->type != OB_GPENCIL) { - return OPERATOR_CANCELLED; - } - - bGPdata *gpd = (bGPdata *)ob->data; - bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); - if (gpl == NULL) { - return OPERATOR_CANCELLED; - } - - int totstrokes = 0; - int totpoints = 0; - - /* count number of strokes and selected points */ - gpencil_get_elements_len(C, &totstrokes, &totpoints); - - if (totpoints == 0) { - return OPERATOR_CANCELLED; - } - - /* calc factor of each point and fill an array with all data */ - tGPencilPointCache *sorted_array = NULL; - tGPencilPointCache *original_array = MEM_callocN(sizeof(tGPencilPointCache) * totpoints, __func__); - gpencil_calc_points_factor(C, mode, totpoints, clear_point, clear_stroke, original_array); - - /* for strokes analyze strokes and load sorted array */ - if (mode == GP_MERGE_STROKE) { - sorted_array = MEM_callocN(sizeof(tGPencilPointCache) * totpoints, __func__); - totpoints = gpencil_analyze_strokes(original_array, totstrokes, totpoints, sorted_array); - } - else { - /* make a copy to sort */ - sorted_array = MEM_dupallocN(original_array); - /* sort by factor around center */ - qsort(sorted_array, totpoints, sizeof(tGPencilPointCache), gpencil_sort_points); - } - - /* prepare the new stroke */ - bGPDstroke *gps = gpencil_prepare_stroke(C, op, totpoints); - - /* copy original points to final stroke */ - gpencil_insert_points_to_stroke(gps, sorted_array, totpoints); - - /* dissolve all tagged points */ - if ((clear_point) || (clear_stroke)) { - gpencil_dissolve_points(C); - } - - /* free memory */ - MEM_SAFE_FREE(original_array); - MEM_SAFE_FREE(sorted_array); - - /* notifiers */ - DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); - - return OPERATOR_FINISHED; + const int mode = RNA_enum_get(op->ptr, "mode"); + const bool clear_point = RNA_boolean_get(op->ptr, "clear_point"); + const bool clear_stroke = RNA_boolean_get(op->ptr, "clear_stroke"); + + Object *ob = CTX_data_active_object(C); + /* sanity checks */ + if (!ob || ob->type != OB_GPENCIL) { + return OPERATOR_CANCELLED; + } + + bGPdata *gpd = (bGPdata *)ob->data; + bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); + if (gpl == NULL) { + return OPERATOR_CANCELLED; + } + + int totstrokes = 0; + int totpoints = 0; + + /* count number of strokes and selected points */ + gpencil_get_elements_len(C, &totstrokes, &totpoints); + + if (totpoints == 0) { + return OPERATOR_CANCELLED; + } + + /* calc factor of each point and fill an array with all data */ + tGPencilPointCache *sorted_array = NULL; + tGPencilPointCache *original_array = MEM_callocN(sizeof(tGPencilPointCache) * totpoints, + __func__); + gpencil_calc_points_factor(C, mode, totpoints, clear_point, clear_stroke, original_array); + + /* for strokes analyze strokes and load sorted array */ + if (mode == GP_MERGE_STROKE) { + sorted_array = MEM_callocN(sizeof(tGPencilPointCache) * totpoints, __func__); + totpoints = gpencil_analyze_strokes(original_array, totstrokes, totpoints, sorted_array); + } + else { + /* make a copy to sort */ + sorted_array = MEM_dupallocN(original_array); + /* sort by factor around center */ + qsort(sorted_array, totpoints, sizeof(tGPencilPointCache), gpencil_sort_points); + } + + /* prepare the new stroke */ + bGPDstroke *gps = gpencil_prepare_stroke(C, op, totpoints); + + /* copy original points to final stroke */ + gpencil_insert_points_to_stroke(gps, sorted_array, totpoints); + + /* dissolve all tagged points */ + if ((clear_point) || (clear_stroke)) { + gpencil_dissolve_points(C); + } + + /* free memory */ + MEM_SAFE_FREE(original_array); + MEM_SAFE_FREE(sorted_array); + + /* notifiers */ + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return OPERATOR_FINISHED; } void GPENCIL_OT_stroke_merge(wmOperatorType *ot) { - static const EnumPropertyItem mode_type[] = { - {GP_MERGE_STROKE, "STROKE", 0, "Stroke", ""}, - {GP_MERGE_POINT, "POINT", 0, "Point", ""}, - {0, NULL, 0, NULL, NULL}, - }; - - /* identifiers */ - ot->name = "Merge Strokes"; - ot->idname = "GPENCIL_OT_stroke_merge"; - ot->description = "Create a new stroke with the selected stroke points"; - - /* api callbacks */ - ot->exec = gp_stroke_merge_exec; - ot->poll = gp_strokes_merge_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - ot->prop = RNA_def_enum(ot->srna, "mode", mode_type, GP_MERGE_STROKE, "Mode", ""); - RNA_def_boolean(ot->srna, "back", 0, "Draw on Back", "Draw new stroke below all previous strokes"); - RNA_def_boolean(ot->srna, "additive", 0, "Additive Drawing", "Add to previous drawing"); - RNA_def_boolean(ot->srna, "cyclic", 0, "Cyclic", "Close new stroke"); - RNA_def_boolean(ot->srna, "clear_point", 0, "Dissolve Points", "Dissolve old selected points"); - RNA_def_boolean(ot->srna, "clear_stroke", 0, "Delete Strokes", "Delete old selected strokes"); + static const EnumPropertyItem mode_type[] = { + {GP_MERGE_STROKE, "STROKE", 0, "Stroke", ""}, + {GP_MERGE_POINT, "POINT", 0, "Point", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + /* identifiers */ + ot->name = "Merge Strokes"; + ot->idname = "GPENCIL_OT_stroke_merge"; + ot->description = "Create a new stroke with the selected stroke points"; + + /* api callbacks */ + ot->exec = gp_stroke_merge_exec; + ot->poll = gp_strokes_merge_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "mode", mode_type, GP_MERGE_STROKE, "Mode", ""); + RNA_def_boolean( + ot->srna, "back", 0, "Draw on Back", "Draw new stroke below all previous strokes"); + RNA_def_boolean(ot->srna, "additive", 0, "Additive Drawing", "Add to previous drawing"); + RNA_def_boolean(ot->srna, "cyclic", 0, "Cyclic", "Close new stroke"); + RNA_def_boolean(ot->srna, "clear_point", 0, "Dissolve Points", "Dissolve old selected points"); + RNA_def_boolean(ot->srna, "clear_stroke", 0, "Delete Strokes", "Delete old selected strokes"); } |