diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2021-03-24 22:55:05 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2021-03-24 22:55:05 +0300 |
commit | 20f4fe138e33e1709cc68e3f297c0c60bdbfb6df (patch) | |
tree | a1dd030a4344ece3b2b5585797752469e75bb2ee /source/blender | |
parent | ecbf642dddc6c29f0e4f04e28055645efa6fc332 (diff) | |
parent | 9ac7946dd03fb75bab591c5ed0a742c00b80286b (diff) |
Merge branch 'master' into sculpt-dev
Diffstat (limited to 'source/blender')
305 files changed, 8202 insertions, 1096 deletions
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index eb5f910f555..c9585430ae2 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -39,7 +39,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 13 +#define BLENDER_FILE_SUBVERSION 14 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h index 89a794f2df3..a9bd0a524c4 100644 --- a/source/blender/blenkernel/BKE_gpencil_geom.h +++ b/source/blender/blenkernel/BKE_gpencil_geom.h @@ -27,10 +27,10 @@ extern "C" { #endif -struct BoundBox; struct Depsgraph; struct Main; struct Object; +struct RegionView3D; struct Scene; struct bGPDcurve; struct bGPDframe; @@ -173,6 +173,20 @@ void BKE_gpencil_stroke_uniform_subdivide(struct bGPdata *gpd, const uint32_t target_number, const bool select); +void BKE_gpencil_stroke_to_view_space(struct RegionView3D *rv3d, + struct bGPDstroke *gps, + const float diff_mat[4][4]); +void BKE_gpencil_stroke_from_view_space(struct RegionView3D *rv3d, + struct bGPDstroke *gps, + const float diff_mat[4][4]); +struct bGPDstroke *BKE_gpencil_stroke_perimeter_from_view(struct RegionView3D *rv3d, + struct bGPdata *gpd, + const struct bGPDlayer *gpl, + struct bGPDstroke *gps, + const int subdivisions, + const float diff_mat[4][4]); +float BKE_gpencil_stroke_average_pressure_get(struct bGPDstroke *gps); +bool BKE_gpencil_stroke_is_pressure_constant(struct bGPDstroke *gps); #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c index ff799d9a495..1075a46e72b 100644 --- a/source/blender/blenkernel/intern/appdir.c +++ b/source/blender/blenkernel/intern/appdir.c @@ -664,7 +664,7 @@ bool BKE_appdir_folder_id_ex(const int folder_id, return false; default: - BLI_assert(0); + BLI_assert_unreachable(); break; } @@ -719,7 +719,7 @@ const char *BKE_appdir_folder_id_user_notest(const int folder_id, const char *su get_path_user_ex(path, sizeof(path), "scripts", subfolder, version, check_is_dir); break; default: - BLI_assert(0); + BLI_assert_unreachable(); break; } diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 92759221f79..a1ebec1d756 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1691,7 +1691,7 @@ void BKE_bone_parent_transform_calc_from_matrices(int bone_flag, break; default: - BLI_assert(false); + BLI_assert_unreachable(); } } /* If removing parent pose rotation: */ @@ -1723,7 +1723,7 @@ void BKE_bone_parent_transform_calc_from_matrices(int bone_flag, break; default: - BLI_assert(false); + BLI_assert_unreachable(); } } diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 44d9bd6b2d2..f30fcc54b23 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -1374,7 +1374,7 @@ void BKE_histogram_update_sample_line(Histogram *hist, rgba[3] = 1.0f; break; default: - BLI_assert(0); + BLI_assert_unreachable(); } hist->data_luma[i] = IMB_colormanagement_get_luminance(rgba); @@ -1476,7 +1476,7 @@ static void scopes_update_cb(void *__restrict userdata, rgba[3] = 1.0f; break; default: - BLI_assert(0); + BLI_assert_unreachable(); } } else { diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 4c85fda4a37..851d8aae378 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -936,7 +936,7 @@ static void update_velocities(FluidEffectorSettings *fes, } else { /* Should never reach this block. */ - BLI_assert(false); + BLI_assert_unreachable(); } } else { diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c index 8c4882854d1..5d8dd99b3ae 100644 --- a/source/blender/blenkernel/intern/gpencil_geom.c +++ b/source/blender/blenkernel/intern/gpencil_geom.c @@ -46,9 +46,11 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "BLT_translation.h" +#include "BKE_context.h" #include "BKE_deform.h" #include "BKE_gpencil.h" #include "BKE_gpencil_curve.h" @@ -3460,4 +3462,555 @@ void BKE_gpencil_stroke_uniform_subdivide(bGPdata *gpd, BKE_gpencil_stroke_geometry_update(gpd, gps); } +/** + * Stroke to view space + * Transforms a stroke to view space. This allows for manipulations in 2D but also easy conversion + * back to 3D. + * Note: also takes care of parent space transform + */ +void BKE_gpencil_stroke_to_view_space(RegionView3D *rv3d, + bGPDstroke *gps, + const float diff_mat[4][4]) +{ + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + /* Point to parent space. */ + mul_v3_m4v3(&pt->x, diff_mat, &pt->x); + /* point to view space */ + mul_m4_v3(rv3d->viewmat, &pt->x); + } +} + +/** + * Stroke from view space + * Transforms a stroke from view space back to world space. Inverse of + * BKE_gpencil_stroke_to_view_space + * Note: also takes care of parent space transform + */ +void BKE_gpencil_stroke_from_view_space(RegionView3D *rv3d, + bGPDstroke *gps, + const float diff_mat[4][4]) +{ + float inverse_diff_mat[4][4]; + invert_m4_m4(inverse_diff_mat, diff_mat); + + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + mul_v3_m4v3(&pt->x, rv3d->viewinv, &pt->x); + mul_m4_v3(inverse_diff_mat, &pt->x); + } +} + +/* ----------------------------------------------------------------------------- */ +/* Stroke to perimeter */ + +typedef struct tPerimeterPoint { + struct tPerimeterPoint *next, *prev; + float x, y, z; +} tPerimeterPoint; + +static tPerimeterPoint *new_perimeter_point(const float pt[3]) +{ + tPerimeterPoint *new_pt = MEM_callocN(sizeof(tPerimeterPoint), __func__); + copy_v3_v3(&new_pt->x, pt); + return new_pt; +} + +static int generate_arc_from_point_to_point(ListBase *list, + tPerimeterPoint *from, + tPerimeterPoint *to, + float center_pt[3], + int subdivisions, + bool clockwise) +{ + float vec_from[2]; + float vec_to[2]; + sub_v2_v2v2(vec_from, &from->x, center_pt); + sub_v2_v2v2(vec_to, &to->x, center_pt); + if (is_zero_v2(vec_from) || is_zero_v2(vec_to)) { + return 0; + } + + float dot = dot_v2v2(vec_from, vec_to); + float det = cross_v2v2(vec_from, vec_to); + float angle = clockwise ? M_PI - atan2f(-det, -dot) : atan2f(-det, -dot) + M_PI; + + /* Number of points is 2^(n+1) + 1 on half a circle (n=subdivisions) + * so we multiply by (angle / pi) to get the right amount of + * points to insert. */ + int num_points = (int)(((1 << (subdivisions + 1)) - 1) * (angle / M_PI)); + if (num_points > 0) { + float angle_incr = angle / (float)num_points; + + float vec_p[3]; + float vec_t[3]; + float tmp_angle; + tPerimeterPoint *last_point; + if (clockwise) { + last_point = to; + copy_v2_v2(vec_t, vec_to); + } + else { + last_point = from; + copy_v2_v2(vec_t, vec_from); + } + + for (int i = 0; i < num_points - 1; i++) { + tmp_angle = (i + 1) * angle_incr; + + rotate_v2_v2fl(vec_p, vec_t, tmp_angle); + add_v2_v2(vec_p, center_pt); + vec_p[2] = center_pt[2]; + + tPerimeterPoint *new_point = new_perimeter_point(vec_p); + if (clockwise) { + BLI_insertlinkbefore(list, last_point, new_point); + } + else { + BLI_insertlinkafter(list, last_point, new_point); + } + + last_point = new_point; + } + + return num_points - 1; + } + + return 0; +} + +static int generate_semi_circle_from_point_to_point(ListBase *list, + tPerimeterPoint *from, + tPerimeterPoint *to, + int subdivisions) +{ + int num_points = (1 << (subdivisions + 1)) + 1; + float center_pt[3]; + interp_v3_v3v3(center_pt, &from->x, &to->x, 0.5f); + + float vec_center[2]; + sub_v2_v2v2(vec_center, &from->x, center_pt); + if (is_zero_v2(vec_center)) { + return 0; + } + + float vec_p[3]; + float angle_incr = M_PI / ((float)num_points - 1); + + tPerimeterPoint *last_point = from; + for (int i = 1; i < num_points; i++) { + float angle = i * angle_incr; + + /* Rotate vector around point to get perimeter points. */ + rotate_v2_v2fl(vec_p, vec_center, angle); + add_v2_v2(vec_p, center_pt); + vec_p[2] = center_pt[2]; + + tPerimeterPoint *new_point = new_perimeter_point(vec_p); + BLI_insertlinkafter(list, last_point, new_point); + + last_point = new_point; + } + + return num_points - 1; +} + +static int generate_perimeter_cap(const float point[4], + const float other_point[4], + float radius, + ListBase *list, + int subdivisions, + short cap_type) +{ + float cap_vec[2]; + sub_v2_v2v2(cap_vec, other_point, point); + normalize_v2(cap_vec); + + float cap_nvec[2]; + if (is_zero_v2(cap_vec)) { + cap_nvec[0] = 0; + cap_nvec[1] = radius; + } + else { + cap_nvec[0] = -cap_vec[1]; + cap_nvec[1] = cap_vec[0]; + mul_v2_fl(cap_nvec, radius); + } + float cap_nvec_inv[2]; + negate_v2_v2(cap_nvec_inv, cap_nvec); + + float vec_perimeter[3]; + copy_v3_v3(vec_perimeter, point); + add_v2_v2(vec_perimeter, cap_nvec); + + float vec_perimeter_inv[3]; + copy_v3_v3(vec_perimeter_inv, point); + add_v2_v2(vec_perimeter_inv, cap_nvec_inv); + + tPerimeterPoint *p_pt = new_perimeter_point(vec_perimeter); + tPerimeterPoint *p_pt_inv = new_perimeter_point(vec_perimeter_inv); + + BLI_addtail(list, p_pt); + BLI_addtail(list, p_pt_inv); + + int num_points = 0; + if (cap_type == GP_STROKE_CAP_ROUND) { + num_points += generate_semi_circle_from_point_to_point(list, p_pt, p_pt_inv, subdivisions); + } + + return num_points + 2; +} + +/** + * Calculate the perimeter (outline) of a stroke as list of tPerimeterPoint. + * \param subdivisions: Number of subdivions for the start and end caps + * \return: list of tPerimeterPoint + */ +static ListBase *gpencil_stroke_perimeter_ex(const bGPdata *gpd, + const bGPDlayer *gpl, + const bGPDstroke *gps, + int subdivisions, + int *r_num_perimeter_points) +{ + /* sanity check */ + if (gps->totpoints < 1) { + return NULL; + } + + float defaultpixsize = 1000.0f / gpd->pixfactor; + float stroke_radius = ((gps->thickness + gpl->line_change) / defaultpixsize) / 2.0f; + + ListBase *perimeter_right_side = MEM_callocN(sizeof(ListBase), __func__); + ListBase *perimeter_left_side = MEM_callocN(sizeof(ListBase), __func__); + int num_perimeter_points = 0; + + bGPDspoint *first = &gps->points[0]; + bGPDspoint *last = &gps->points[gps->totpoints - 1]; + + float first_radius = stroke_radius * first->pressure; + float last_radius = stroke_radius * last->pressure; + + bGPDspoint *first_next; + bGPDspoint *last_prev; + if (gps->totpoints > 1) { + first_next = &gps->points[1]; + last_prev = &gps->points[gps->totpoints - 2]; + } + else { + first_next = first; + last_prev = last; + } + + float first_pt[3]; + float last_pt[3]; + float first_next_pt[3]; + float last_prev_pt[3]; + copy_v3_v3(first_pt, &first->x); + copy_v3_v3(last_pt, &last->x); + copy_v3_v3(first_next_pt, &first_next->x); + copy_v3_v3(last_prev_pt, &last_prev->x); + + /* edgecase if single point */ + if (gps->totpoints == 1) { + first_next_pt[0] += 1.0f; + last_prev_pt[0] -= 1.0f; + } + + /* generate points for start cap */ + num_perimeter_points += generate_perimeter_cap( + first_pt, first_next_pt, first_radius, perimeter_right_side, subdivisions, gps->caps[0]); + + /* generate perimeter points */ + float curr_pt[3], next_pt[3], prev_pt[3]; + float vec_next[2], vec_prev[2]; + float nvec_next[2], nvec_prev[2]; + float nvec_next_pt[3], nvec_prev_pt[3]; + float vec_tangent[2]; + + float vec_miter_left[2], vec_miter_right[2]; + float miter_left_pt[3], miter_right_pt[3]; + + for (int i = 1; i < gps->totpoints - 1; i++) { + bGPDspoint *curr = &gps->points[i]; + bGPDspoint *prev = &gps->points[i - 1]; + bGPDspoint *next = &gps->points[i + 1]; + float radius = stroke_radius * curr->pressure; + + copy_v3_v3(curr_pt, &curr->x); + copy_v3_v3(next_pt, &next->x); + copy_v3_v3(prev_pt, &prev->x); + + sub_v2_v2v2(vec_prev, curr_pt, prev_pt); + sub_v2_v2v2(vec_next, next_pt, curr_pt); + float prev_length = len_v2(vec_prev); + float next_length = len_v2(vec_next); + + if (normalize_v2(vec_prev) == 0.0f) { + vec_prev[0] = 1.0f; + vec_prev[1] = 0.0f; + } + if (normalize_v2(vec_next) == 0.0f) { + vec_next[0] = 1.0f; + vec_next[1] = 0.0f; + } + + nvec_prev[0] = -vec_prev[1]; + nvec_prev[1] = vec_prev[0]; + + nvec_next[0] = -vec_next[1]; + nvec_next[1] = vec_next[0]; + + add_v2_v2v2(vec_tangent, vec_prev, vec_next); + if (normalize_v2(vec_tangent) == 0.0f) { + copy_v2_v2(vec_tangent, nvec_prev); + } + + vec_miter_left[0] = -vec_tangent[1]; + vec_miter_left[1] = vec_tangent[0]; + + /* calculate miter length */ + float an1 = dot_v2v2(vec_miter_left, nvec_prev); + if (an1 == 0.0f) { + an1 = 1.0f; + } + float miter_length = radius / an1; + if (miter_length <= 0.0f) { + miter_length = 0.01f; + } + + normalize_v2_length(vec_miter_left, miter_length); + + copy_v2_v2(vec_miter_right, vec_miter_left); + negate_v2(vec_miter_right); + + float angle = dot_v2v2(vec_next, nvec_prev); + /* add two points if angle is close to beeing straight */ + if (fabsf(angle) < 0.0001f) { + normalize_v2_length(nvec_prev, radius); + normalize_v2_length(nvec_next, radius); + + copy_v3_v3(nvec_prev_pt, curr_pt); + add_v2_v2(nvec_prev_pt, nvec_prev); + + copy_v3_v3(nvec_next_pt, curr_pt); + negate_v2(nvec_next); + add_v2_v2(nvec_next_pt, nvec_next); + + tPerimeterPoint *normal_prev = new_perimeter_point(nvec_prev_pt); + tPerimeterPoint *normal_next = new_perimeter_point(nvec_next_pt); + + BLI_addtail(perimeter_left_side, normal_prev); + BLI_addtail(perimeter_right_side, normal_next); + num_perimeter_points += 2; + } + else { + /* bend to the left */ + if (angle < 0.0f) { + normalize_v2_length(nvec_prev, radius); + normalize_v2_length(nvec_next, radius); + + copy_v3_v3(nvec_prev_pt, curr_pt); + add_v2_v2(nvec_prev_pt, nvec_prev); + + copy_v3_v3(nvec_next_pt, curr_pt); + add_v2_v2(nvec_next_pt, nvec_next); + + tPerimeterPoint *normal_prev = new_perimeter_point(nvec_prev_pt); + tPerimeterPoint *normal_next = new_perimeter_point(nvec_next_pt); + + BLI_addtail(perimeter_left_side, normal_prev); + BLI_addtail(perimeter_left_side, normal_next); + num_perimeter_points += 2; + + num_perimeter_points += generate_arc_from_point_to_point( + perimeter_left_side, normal_prev, normal_next, curr_pt, subdivisions, true); + + if (miter_length < prev_length && miter_length < next_length) { + copy_v3_v3(miter_right_pt, curr_pt); + add_v2_v2(miter_right_pt, vec_miter_right); + } + else { + copy_v3_v3(miter_right_pt, curr_pt); + negate_v2(nvec_next); + add_v2_v2(miter_right_pt, nvec_next); + } + + tPerimeterPoint *miter_right = new_perimeter_point(miter_right_pt); + BLI_addtail(perimeter_right_side, miter_right); + num_perimeter_points++; + } + /* bend to the right */ + else { + normalize_v2_length(nvec_prev, -radius); + normalize_v2_length(nvec_next, -radius); + + copy_v3_v3(nvec_prev_pt, curr_pt); + add_v2_v2(nvec_prev_pt, nvec_prev); + + copy_v3_v3(nvec_next_pt, curr_pt); + add_v2_v2(nvec_next_pt, nvec_next); + + tPerimeterPoint *normal_prev = new_perimeter_point(nvec_prev_pt); + tPerimeterPoint *normal_next = new_perimeter_point(nvec_next_pt); + + BLI_addtail(perimeter_right_side, normal_prev); + BLI_addtail(perimeter_right_side, normal_next); + num_perimeter_points += 2; + + num_perimeter_points += generate_arc_from_point_to_point( + perimeter_right_side, normal_prev, normal_next, curr_pt, subdivisions, false); + + if (miter_length < prev_length && miter_length < next_length) { + copy_v3_v3(miter_left_pt, curr_pt); + add_v2_v2(miter_left_pt, vec_miter_left); + } + else { + copy_v3_v3(miter_left_pt, curr_pt); + negate_v2(nvec_prev); + add_v2_v2(miter_left_pt, nvec_prev); + } + + tPerimeterPoint *miter_left = new_perimeter_point(miter_left_pt); + BLI_addtail(perimeter_left_side, miter_left); + num_perimeter_points++; + } + } + } + + /* generate points for end cap */ + num_perimeter_points += generate_perimeter_cap( + last_pt, last_prev_pt, last_radius, perimeter_right_side, subdivisions, gps->caps[1]); + + /* merge both sides to one list */ + BLI_listbase_reverse(perimeter_right_side); + BLI_movelisttolist(perimeter_left_side, + perimeter_right_side); // perimeter_left_side contains entire list + ListBase *perimeter_list = perimeter_left_side; + + /* close by creating a point close to the first (make a small gap) */ + float close_pt[3]; + tPerimeterPoint *close_first = (tPerimeterPoint *)perimeter_list->first; + tPerimeterPoint *close_last = (tPerimeterPoint *)perimeter_list->last; + interp_v3_v3v3(close_pt, &close_last->x, &close_first->x, 0.99f); + + if (compare_v3v3(close_pt, &close_first->x, FLT_EPSILON) == false) { + tPerimeterPoint *close_p_pt = new_perimeter_point(close_pt); + BLI_addtail(perimeter_list, close_p_pt); + num_perimeter_points++; + } + + /* free temp data */ + BLI_freelistN(perimeter_right_side); + MEM_freeN(perimeter_right_side); + + *r_num_perimeter_points = num_perimeter_points; + return perimeter_list; +} + +/** + * Calculates the perimeter of a stroke projected from the view and + * returns it as a new stroke. + * \param subdivisions: Number of subdivions for the start and end caps + * \return: bGPDstroke pointer to stroke perimeter + */ +bGPDstroke *BKE_gpencil_stroke_perimeter_from_view(struct RegionView3D *rv3d, + bGPdata *gpd, + const bGPDlayer *gpl, + bGPDstroke *gps, + const int subdivisions, + const float diff_mat[4][4]) +{ + if (gps->totpoints == 0) { + return NULL; + } + bGPDstroke *gps_temp = BKE_gpencil_stroke_duplicate(gps, true, false); + const bool cyclic = ((gps_temp->flag & GP_STROKE_CYCLIC) != 0); + + /* If Cyclic, add a new point. */ + if (cyclic && (gps_temp->totpoints > 1)) { + gps_temp->totpoints++; + gps_temp->points = MEM_recallocN(gps_temp->points, + sizeof(*gps_temp->points) * gps_temp->totpoints); + bGPDspoint *pt_src = &gps_temp->points[0]; + bGPDspoint *pt_dst = &gps_temp->points[gps_temp->totpoints - 1]; + copy_v3_v3(&pt_dst->x, &pt_src->x); + pt_dst->pressure = pt_src->pressure; + pt_dst->strength = pt_src->strength; + pt_dst->uv_fac = 1.0f; + pt_dst->uv_rot = 0; + } + + BKE_gpencil_stroke_to_view_space(rv3d, gps_temp, diff_mat); + int num_perimeter_points = 0; + ListBase *perimeter_points = gpencil_stroke_perimeter_ex( + gpd, gpl, gps_temp, subdivisions, &num_perimeter_points); + + if (num_perimeter_points == 0) { + return NULL; + } + + /* Create new stroke. */ + bGPDstroke *perimeter_stroke = BKE_gpencil_stroke_new(gps_temp->mat_nr, num_perimeter_points, 1); + + int i = 0; + LISTBASE_FOREACH_INDEX (tPerimeterPoint *, curr, perimeter_points, i) { + bGPDspoint *pt = &perimeter_stroke->points[i]; + + copy_v3_v3(&pt->x, &curr->x); + pt->pressure = 0.0f; + pt->strength = 1.0f; + + pt->flag |= GP_SPOINT_SELECT; + } + + BKE_gpencil_stroke_from_view_space(rv3d, perimeter_stroke, diff_mat); + + /* Free temp data. */ + BLI_freelistN(perimeter_points); + MEM_freeN(perimeter_points); + + /* Triangles cache needs to be recalculated. */ + BKE_gpencil_stroke_geometry_update(gpd, perimeter_stroke); + + perimeter_stroke->flag |= GP_STROKE_SELECT | GP_STROKE_CYCLIC; + + BKE_gpencil_free_stroke(gps_temp); + + return perimeter_stroke; +} + +/** Get average pressure. */ +float BKE_gpencil_stroke_average_pressure_get(bGPDstroke *gps) +{ + + if (gps->totpoints == 1) { + return gps->points[0].pressure; + } + + float tot = 0.0f; + for (int i = 0; i < gps->totpoints; i++) { + const bGPDspoint *pt = &gps->points[i]; + tot += pt->pressure; + } + + return tot / (float)gps->totpoints; +} + +/** Check if the thickness of the stroke is constant. */ +bool BKE_gpencil_stroke_is_pressure_constant(bGPDstroke *gps) +{ + if (gps->totpoints == 1) { + return true; + } + + const float first_pressure = gps->points[0].pressure; + for (int i = 0; i < gps->totpoints; i++) { + const bGPDspoint *pt = &gps->points[i]; + if (pt->pressure != first_pressure) { + return false; + } + } + + return true; +} /** \} */ diff --git a/source/blender/blenkernel/intern/keyconfig.c b/source/blender/blenkernel/intern/keyconfig.c index ada5fc5b6aa..552760c9b34 100644 --- a/source/blender/blenkernel/intern/keyconfig.c +++ b/source/blender/blenkernel/intern/keyconfig.c @@ -19,6 +19,7 @@ */ #include <stddef.h> +#include <stdio.h> #include <stdlib.h> #include "RNA_types.h" diff --git a/source/blender/blenkernel/intern/main.c b/source/blender/blenkernel/intern/main.c index d1f34ad8ce9..dc678f248c9 100644 --- a/source/blender/blenkernel/intern/main.c +++ b/source/blender/blenkernel/intern/main.c @@ -182,7 +182,7 @@ void BKE_main_free(Main *mainvar) BKE_id_free_ex(mainvar, id, free_flag, false); break; default: - BLI_assert(0); + BLI_assert_unreachable(); break; } #endif diff --git a/source/blender/blenkernel/intern/mesh_wrapper.c b/source/blender/blenkernel/intern/mesh_wrapper.c index acd272ac305..5df9f7816e3 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.c +++ b/source/blender/blenkernel/intern/mesh_wrapper.c @@ -148,7 +148,7 @@ bool BKE_mesh_wrapper_minmax(const Mesh *me, float min[3], float max[3]) case ME_WRAPPER_TYPE_MDATA: return BKE_mesh_minmax(me, min, max); } - BLI_assert(0); + BLI_assert_unreachable(); return false; } @@ -189,7 +189,7 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me, return; } } - BLI_assert(0); + BLI_assert_unreachable(); } void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me, @@ -226,7 +226,7 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me, return; } } - BLI_assert(0); + BLI_assert_unreachable(); } /** \} */ @@ -243,7 +243,7 @@ int BKE_mesh_wrapper_vert_len(const Mesh *me) case ME_WRAPPER_TYPE_MDATA: return me->totvert; } - BLI_assert(0); + BLI_assert_unreachable(); return -1; } @@ -255,7 +255,7 @@ int BKE_mesh_wrapper_edge_len(const Mesh *me) case ME_WRAPPER_TYPE_MDATA: return me->totedge; } - BLI_assert(0); + BLI_assert_unreachable(); return -1; } @@ -267,7 +267,7 @@ int BKE_mesh_wrapper_loop_len(const Mesh *me) case ME_WRAPPER_TYPE_MDATA: return me->totloop; } - BLI_assert(0); + BLI_assert_unreachable(); return -1; } @@ -279,7 +279,7 @@ int BKE_mesh_wrapper_poly_len(const Mesh *me) case ME_WRAPPER_TYPE_MDATA: return me->totpoly; } - BLI_assert(0); + BLI_assert_unreachable(); return -1; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 00e99f193a2..b07c4b22c39 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1858,7 +1858,7 @@ bool BKE_object_data_is_in_editmode(const ID *id) case ID_AR: return ((const bArmature *)id)->edbo != NULL; default: - BLI_assert(0); + BLI_assert_unreachable(); return false; } } @@ -1905,7 +1905,7 @@ char *BKE_object_data_editmode_flush_ptr_get(struct ID *id) return &arm->needs_flush_to_id; } default: - BLI_assert(0); + BLI_assert_unreachable(); return NULL; } return NULL; diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 2e81b61ad8c..3494630e1fa 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -656,7 +656,7 @@ void BKE_paint_runtime_init(const ToolSettings *ts, Paint *paint) paint->runtime.ob_mode = OB_MODE_WEIGHT_GPENCIL; } else { - BLI_assert(0); + BLI_assert_unreachable(); } } diff --git a/source/blender/blenkernel/intern/text_suggestions.c b/source/blender/blenkernel/intern/text_suggestions.c index 6df1aff722b..d717b88e8ca 100644 --- a/source/blender/blenkernel/intern/text_suggestions.c +++ b/source/blender/blenkernel/intern/text_suggestions.c @@ -22,6 +22,7 @@ */ #include <ctype.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index 52f0fe3f5a2..377802f1af7 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -20,6 +20,7 @@ * Used by ED_undo.h, internal implementation. */ +#include <stdio.h> #include <string.h> #include "CLG_log.h" diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c index 481d190952f..be67b2370e3 100644 --- a/source/blender/blenkernel/intern/workspace.c +++ b/source/blender/blenkernel/intern/workspace.c @@ -18,6 +18,7 @@ * \ingroup bke */ +#include <stdio.h> #include <stdlib.h> #include <string.h> diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c index 07ab4f407f2..70a51982925 100644 --- a/source/blender/blenlib/intern/BLI_args.c +++ b/source/blender/blenlib/intern/BLI_args.c @@ -23,6 +23,7 @@ */ #include <ctype.h> /* for tolower */ +#include <stdio.h> #include <string.h> #include "MEM_guardedalloc.h" diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c index 3e80f791fa5..7b25fecfa45 100644 --- a/source/blender/blenlib/intern/BLI_dynstr.c +++ b/source/blender/blenlib/intern/BLI_dynstr.c @@ -22,6 +22,7 @@ * \ingroup bli */ +#include <stdio.h> #include <stdlib.h> /* malloc */ #include <string.h> diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index 05ee02ad869..b8bf535a3b4 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -24,6 +24,7 @@ */ #include <limits.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 3bfedd6f586..ccc11af9f2b 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -25,6 +25,7 @@ #include <inttypes.h> #include <math.h> #include <stdarg.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> diff --git a/source/blender/blenlib/intern/string_search.cc b/source/blender/blenlib/intern/string_search.cc index 44baff1f5e3..25a13674932 100644 --- a/source/blender/blenlib/intern/string_search.cc +++ b/source/blender/blenlib/intern/string_search.cc @@ -432,9 +432,11 @@ int BLI_string_search_query(StringSearch *search, const char *query, void ***r_d { using namespace blender; + const StringRef query_str = query; + LinearAllocator<> allocator; Vector<StringRef, 64> query_words; - string_search::extract_normalized_words(query, allocator, query_words); + string_search::extract_normalized_words(query_str, allocator, query_words); /* Compute score of every result. */ MultiValueMap<int, int> result_indices_by_score; @@ -457,7 +459,7 @@ int BLI_string_search_query(StringSearch *search, const char *query, void ***r_d Vector<int> sorted_result_indices; for (const int score : found_scores) { MutableSpan<int> indices = result_indices_by_score.lookup(score); - if (score == found_scores[0]) { + if (score == found_scores[0] && !query_str.is_empty()) { /* Sort items with best score by length. Shorter items are more likely the ones you are * looking for. This also ensures that exact matches will be at the top, even if the query is * a substring of another item. */ diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index a2be00294f2..b2461710cea 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -53,6 +53,7 @@ #include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_brush.h" +#include "BKE_attribute.h" #include "BKE_collection.h" #include "BKE_colortools.h" #include "BKE_cryptomatte.h" @@ -1906,6 +1907,25 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 293, 14)) { + if (!DNA_struct_elem_find(fd->filesdna, "Light", "float", "diff_fac")) { + LISTBASE_FOREACH (Light *, light, &bmain->lights) { + light->diff_fac = 1.0f; + light->volume_fac = 1.0f; + } + } + + LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) { + if (ntree->type == NTREE_GEOMETRY) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + if (node->type == GEO_NODE_ATTRIBUTE_FILL) { + node->custom2 = ATTR_DOMAIN_AUTO; + } + } + } + } + } + /** * Versioning code until next subversion bump goes here. * @@ -1929,19 +1949,5 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } - - FOREACH_NODETREE_BEGIN (bmain, ntree, id) { - if (ntree->type == NTREE_GEOMETRY) { - version_node_socket_name(ntree, GEO_NODE_ATTRIBUTE_PROXIMITY, "Location", "Position"); - } - } - FOREACH_NODETREE_END; - - if (!DNA_struct_elem_find(fd->filesdna, "Light", "float", "diff_fac")) { - LISTBASE_FOREACH (Light *, light, &bmain->lights) { - light->diff_fac = 1.0f; - light->volume_fac = 1.0f; - } - } } } diff --git a/source/blender/compositor/intern/COM_CPUDevice.h b/source/blender/compositor/intern/COM_CPUDevice.h index 962380d7bc8..6df1f41419d 100644 --- a/source/blender/compositor/intern/COM_CPUDevice.h +++ b/source/blender/compositor/intern/COM_CPUDevice.h @@ -33,7 +33,7 @@ class CPUDevice : public Device { * \brief execute a WorkPackage * \param work: the WorkPackage to execute */ - void execute(WorkPackage *work); + void execute(WorkPackage *work) override; int thread_id() { diff --git a/source/blender/compositor/intern/COM_Device.h b/source/blender/compositor/intern/COM_Device.h index 0b0f0f5c1c6..0a456760045 100644 --- a/source/blender/compositor/intern/COM_Device.h +++ b/source/blender/compositor/intern/COM_Device.h @@ -37,21 +37,6 @@ class Device { } /** - * \brief initialize the device - */ - virtual bool initialize() - { - return true; - } - - /** - * \brief deinitialize the device - */ - virtual void deinitialize() - { - } - - /** * \brief execute a WorkPackage * \param work: the WorkPackage to execute */ diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cc b/source/blender/compositor/intern/COM_ExecutionGroup.cc index 3cedc5da663..f500327b7a7 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cc +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cc @@ -65,7 +65,7 @@ ExecutionGroup::ExecutionGroup() this->m_executionStartTime = 0; } -CompositorPriority ExecutionGroup::getRenderPriotrity() +CompositorPriority ExecutionGroup::getRenderPriority() { return this->getOutputOperation()->getRenderPriority(); } @@ -130,9 +130,7 @@ void ExecutionGroup::initExecution() if (this->m_chunks_len != 0) { m_chunk_execution_states.resize(this->m_chunks_len); - for (int index = 0; index < this->m_chunks_len; index++) { - m_chunk_execution_states[index] = eChunkExecutionState::NOT_SCHEDULED; - } + m_chunk_execution_states.fill(eChunkExecutionState::NOT_SCHEDULED); } unsigned int max_offset = 0; @@ -185,7 +183,6 @@ void ExecutionGroup::determineNumberOfChunks() blender::Array<unsigned int> ExecutionGroup::determine_chunk_execution_order() const { - int index; blender::Array<unsigned int> chunk_order(m_chunks_len); for (int chunk_index = 0; chunk_index < this->m_chunks_len; chunk_index++) { chunk_order[chunk_index] = chunk_index; @@ -205,7 +202,7 @@ blender::Array<unsigned int> ExecutionGroup::determine_chunk_execution_order() c const int border_width = BLI_rcti_size_x(&this->m_viewerBorder); const int border_height = BLI_rcti_size_y(&this->m_viewerBorder); - + int index; switch (order_type) { case ChunkOrdering::Random: { static blender::RandomNumberGenerator rng; @@ -303,7 +300,6 @@ void ExecutionGroup::execute(ExecutionSystem *graph) this->m_chunks_finished = 0; this->m_bTree = bTree; - unsigned int index; blender::Array<unsigned int> chunk_order = determine_chunk_execution_order(); @@ -320,7 +316,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph) finished = true; int numberEvaluated = 0; - for (index = startIndex; index < this->m_chunks_len && numberEvaluated < maxNumberEvaluated; + for (int index = startIndex; + index < this->m_chunks_len && numberEvaluated < maxNumberEvaluated; index++) { chunk_index = chunk_order[index]; int yChunk = chunk_index / this->m_x_chunks_len; diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index 6fd93d2d93c..13ff06cd5d1 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -424,7 +424,7 @@ class ExecutionGroup { * \brief get the Render priority of this ExecutionGroup * \see ExecutionSystem.execute */ - CompositorPriority getRenderPriotrity(); + CompositorPriority getRenderPriority(); /** * \brief set border for viewer operation diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cc b/source/blender/compositor/intern/COM_ExecutionSystem.cc index 993aedf7715..df97b8079b2 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cc +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cc @@ -71,7 +71,6 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, builder.convertToOperations(this); } - unsigned int index; unsigned int resolution[2]; rctf *viewer_border = &editingtree->viewer_border; @@ -81,10 +80,9 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, editingtree->stats_draw(editingtree->sdh, TIP_("Compositing | Determining resolution")); - for (index = 0; index < this->m_groups.size(); index++) { + for (ExecutionGroup *executionGroup : m_groups) { resolution[0] = 0; resolution[1] = 0; - ExecutionGroup *executionGroup = this->m_groups[index]; executionGroup->determineResolution(resolution); if (rendering) { @@ -108,14 +106,12 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, ExecutionSystem::~ExecutionSystem() { - unsigned int index; - for (index = 0; index < this->m_operations.size(); index++) { - NodeOperation *operation = this->m_operations[index]; + for (NodeOperation *operation : m_operations) { delete operation; } this->m_operations.clear(); - for (index = 0; index < this->m_groups.size(); index++) { - ExecutionGroup *group = this->m_groups[index]; + + for (ExecutionGroup *group : m_groups) { delete group; } this->m_groups.clear(); @@ -128,92 +124,98 @@ void ExecutionSystem::set_operations(const blender::Vector<NodeOperation *> &ope m_groups = groups; } -void ExecutionSystem::execute() +static void update_read_buffer_offset(blender::Vector<NodeOperation *> &operations) { - const bNodeTree *editingtree = this->m_context.getbNodeTree(); - editingtree->stats_draw(editingtree->sdh, TIP_("Compositing | Initializing execution")); - - DebugInfo::execute_started(this); - unsigned int order = 0; - for (NodeOperation *operation : m_operations) { + for (NodeOperation *operation : operations) { if (operation->isReadBufferOperation()) { ReadBufferOperation *readOperation = (ReadBufferOperation *)operation; readOperation->setOffset(order); order++; } } - unsigned int index; +} - // First allocale all write buffer - for (index = 0; index < this->m_operations.size(); index++) { - NodeOperation *operation = this->m_operations[index]; +static void init_write_operations_for_execution(blender::Vector<NodeOperation *> &operations, + const bNodeTree *bTree) +{ + for (NodeOperation *operation : operations) { if (operation->isWriteBufferOperation()) { - operation->setbNodeTree(this->m_context.getbNodeTree()); + operation->setbNodeTree(bTree); operation->initExecution(); } } - // Connect read buffers to their write buffers - for (index = 0; index < this->m_operations.size(); index++) { - NodeOperation *operation = this->m_operations[index]; +} + +static void link_write_buffers(blender::Vector<NodeOperation *> &operations) +{ + for (NodeOperation *operation : operations) { if (operation->isReadBufferOperation()) { - ReadBufferOperation *readOperation = (ReadBufferOperation *)operation; + ReadBufferOperation *readOperation = static_cast<ReadBufferOperation *>(operation); readOperation->updateMemoryBuffer(); } } - // initialize other operations - for (index = 0; index < this->m_operations.size(); index++) { - NodeOperation *operation = this->m_operations[index]; +} + +static void init_non_write_operations_for_execution(blender::Vector<NodeOperation *> &operations, + const bNodeTree *bTree) +{ + for (NodeOperation *operation : operations) { if (!operation->isWriteBufferOperation()) { - operation->setbNodeTree(this->m_context.getbNodeTree()); + operation->setbNodeTree(bTree); operation->initExecution(); } } - for (index = 0; index < this->m_groups.size(); index++) { - ExecutionGroup *executionGroup = this->m_groups[index]; - executionGroup->setChunksize(this->m_context.getChunksize()); - executionGroup->initExecution(); +} + +static void init_execution_groups_for_execution(blender::Vector<ExecutionGroup *> &groups, + const int chunk_size) +{ + for (ExecutionGroup *execution_group : groups) { + execution_group->setChunksize(chunk_size); + execution_group->initExecution(); } +} - WorkScheduler::start(this->m_context); +void ExecutionSystem::execute() +{ + const bNodeTree *editingtree = this->m_context.getbNodeTree(); + editingtree->stats_draw(editingtree->sdh, TIP_("Compositing | Initializing execution")); + + DebugInfo::execute_started(this); + update_read_buffer_offset(m_operations); + init_write_operations_for_execution(m_operations, m_context.getbNodeTree()); + link_write_buffers(m_operations); + init_non_write_operations_for_execution(m_operations, m_context.getbNodeTree()); + init_execution_groups_for_execution(m_groups, m_context.getChunksize()); + + WorkScheduler::start(this->m_context); execute_groups(CompositorPriority::High); if (!this->getContext().isFastCalculation()) { execute_groups(CompositorPriority::Medium); execute_groups(CompositorPriority::Low); } - WorkScheduler::finish(); WorkScheduler::stop(); editingtree->stats_draw(editingtree->sdh, TIP_("Compositing | De-initializing execution")); - for (index = 0; index < this->m_operations.size(); index++) { - NodeOperation *operation = this->m_operations[index]; + + for (NodeOperation *operation : m_operations) { operation->deinitExecution(); } - for (index = 0; index < this->m_groups.size(); index++) { - ExecutionGroup *executionGroup = this->m_groups[index]; - executionGroup->deinitExecution(); - } -} -void ExecutionSystem::execute_groups(CompositorPriority priority) -{ - blender::Vector<ExecutionGroup *> execution_groups = find_output_execution_groups(priority); - for (ExecutionGroup *group : execution_groups) { - group->execute(this); + for (ExecutionGroup *execution_group : m_groups) { + execution_group->deinitExecution(); } } -blender::Vector<ExecutionGroup *> ExecutionSystem::find_output_execution_groups( - CompositorPriority priority) const +void ExecutionSystem::execute_groups(CompositorPriority priority) { - blender::Vector<ExecutionGroup *> result; - - for (ExecutionGroup *group : m_groups) { - if (group->isOutputExecutionGroup() && group->getRenderPriotrity() == priority) { - result.append(group); + for (ExecutionGroup *execution_group : m_groups) { + if (execution_group->isOutputExecutionGroup() && + execution_group->getRenderPriority() == priority) { + execution_group->execute(this); } } - return result; } diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h index 6a50cc6906b..c12380fe839 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ b/source/blender/compositor/intern/COM_ExecutionSystem.h @@ -135,12 +135,6 @@ class ExecutionSystem { blender::Vector<ExecutionGroup *> m_groups; private: // methods - /** - * find all execution group with output nodes - */ - blender::Vector<ExecutionGroup *> find_output_execution_groups( - CompositorPriority priority) const; - public: /** * \brief Create a new ExecutionSystem and initialize it with the diff --git a/source/blender/compositor/intern/COM_MemoryProxy.h b/source/blender/compositor/intern/COM_MemoryProxy.h index a40e6f95dce..ee98ff41630 100644 --- a/source/blender/compositor/intern/COM_MemoryProxy.h +++ b/source/blender/compositor/intern/COM_MemoryProxy.h @@ -45,16 +45,6 @@ class MemoryProxy { ExecutionGroup *m_executor; /** - * \brief datatype of this MemoryProxy - */ - /* DataType m_datatype; */ /* UNUSED */ - - /** - * \brief channel information of this buffer - */ - /* ChannelInfo m_channelInfo[COM_NUMBER_OF_CHANNELS]; */ /* UNUSED */ - - /** * \brief the allocated memory */ MemoryBuffer *m_buffer; diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cc b/source/blender/compositor/intern/COM_OpenCLDevice.cc index 9a6012e5c68..4ac6bd50380 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.cc +++ b/source/blender/compositor/intern/COM_OpenCLDevice.cc @@ -43,16 +43,12 @@ OpenCLDevice::OpenCLDevice(cl_context context, this->m_program = program; this->m_queue = nullptr; this->m_vendorID = vendorId; -} -bool OpenCLDevice::initialize() -{ cl_int error; this->m_queue = clCreateCommandQueue(this->m_context, this->m_device, 0, &error); - return false; } -void OpenCLDevice::deinitialize() +OpenCLDevice::~OpenCLDevice() { if (this->m_queue) { clReleaseCommandQueue(this->m_queue); diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.h b/source/blender/compositor/intern/COM_OpenCLDevice.h index e4fd397b4e8..30d9a59d182 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.h +++ b/source/blender/compositor/intern/COM_OpenCLDevice.h @@ -65,26 +65,13 @@ class OpenCLDevice : public Device { * \param vendorID: */ OpenCLDevice(cl_context context, cl_device_id device, cl_program program, cl_int vendorId); - - /** - * \brief initialize the device - * During initialization the OpenCL cl_command_queue is created - * the command queue is stored in the field queue. - * \see queue - */ - bool initialize(); - - /** - * \brief de-initialize the device - * During de-initialization the command queue is cleared - */ - void deinitialize(); + ~OpenCLDevice(); /** * \brief execute a WorkPackage * \param work: the WorkPackage to execute */ - void execute(WorkPackage *work); + void execute(WorkPackage *work) override; /** * \brief determine an image format diff --git a/source/blender/compositor/intern/COM_SingleThreadedOperation.h b/source/blender/compositor/intern/COM_SingleThreadedOperation.h index 32f4515cf2a..82326b57b57 100644 --- a/source/blender/compositor/intern/COM_SingleThreadedOperation.h +++ b/source/blender/compositor/intern/COM_SingleThreadedOperation.h @@ -36,23 +36,23 @@ class SingleThreadedOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; virtual MemoryBuffer *createMemoryBuffer(rcti *rect) = 0; - int isSingleThreaded() + int isSingleThreaded() override { return true; } diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cc b/source/blender/compositor/intern/COM_WorkScheduler.cc index 2bc3ff936b1..7d9dd502762 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cc +++ b/source/blender/compositor/intern/COM_WorkScheduler.cc @@ -70,7 +70,7 @@ static struct { /** \brief list of all CPUDevices. for every hardware thread an instance of CPUDevice is * created */ - blender::Vector<CPUDevice *> devices; + blender::Vector<CPUDevice> devices; /** \brief list of all thread for every CPUDevice in cpudevices a thread exists. */ ListBase threads; @@ -89,7 +89,7 @@ static struct { cl_program program; /** \brief list of all OpenCLDevices. for every OpenCL GPU device an instance of OpenCLDevice * is created. */ - blender::Vector<OpenCLDevice *> devices; + blender::Vector<OpenCLDevice> devices; /** \brief list of all thread for every GPUDevice in cpudevices a thread exists. */ ListBase threads; /** \brief all scheduled work for the GPU. */ @@ -130,9 +130,8 @@ static void opencl_start(CompositorContext &context) BLI_threadpool_init(&g_work_scheduler.opencl.threads, thread_execute_gpu, g_work_scheduler.opencl.devices.size()); - for (int index = 0; index < g_work_scheduler.opencl.devices.size(); index++) { - Device *device = g_work_scheduler.opencl.devices[index]; - BLI_threadpool_insert(&g_work_scheduler.opencl.threads, device); + for (Device &device : g_work_scheduler.opencl.devices) { + BLI_threadpool_insert(&g_work_scheduler.opencl.threads, &device); } g_work_scheduler.opencl.active = true; } @@ -263,12 +262,10 @@ static void opencl_initialize(const bool use_opencl) if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error2, clewErrorString(error2)); } - OpenCLDevice *clDevice = new OpenCLDevice(g_work_scheduler.opencl.context, - device, - g_work_scheduler.opencl.program, - vendorID); - clDevice->initialize(); - g_work_scheduler.opencl.devices.append(clDevice); + g_work_scheduler.opencl.devices.append(OpenCLDevice(g_work_scheduler.opencl.context, + device, + g_work_scheduler.opencl.program, + vendorID)); } } MEM_freeN(cldevices); @@ -282,25 +279,19 @@ static void opencl_initialize(const bool use_opencl) static void opencl_deinitialize() { - /* Deinitialize OpenCL GPU's. */ - if (g_work_scheduler.opencl.initialized) { - Device *device; - while (!g_work_scheduler.opencl.devices.is_empty()) { - device = g_work_scheduler.opencl.devices.pop_last(); - device->deinitialize(); - delete device; - } - if (g_work_scheduler.opencl.program) { - clReleaseProgram(g_work_scheduler.opencl.program); - g_work_scheduler.opencl.program = nullptr; - } - if (g_work_scheduler.opencl.context) { - clReleaseContext(g_work_scheduler.opencl.context); - g_work_scheduler.opencl.context = nullptr; - } + g_work_scheduler.opencl.devices.clear_and_make_inline(); - g_work_scheduler.opencl.initialized = false; + if (g_work_scheduler.opencl.program) { + clReleaseProgram(g_work_scheduler.opencl.program); + g_work_scheduler.opencl.program = nullptr; + } + + if (g_work_scheduler.opencl.context) { + clReleaseContext(g_work_scheduler.opencl.context); + g_work_scheduler.opencl.context = nullptr; } + + g_work_scheduler.opencl.initialized = false; } /* \} */ @@ -346,9 +337,8 @@ static void threading_model_queue_start() BLI_threadpool_init(&g_work_scheduler.queue.threads, threading_model_queue_execute, g_work_scheduler.queue.devices.size()); - for (int index = 0; index < g_work_scheduler.queue.devices.size(); index++) { - Device *device = g_work_scheduler.queue.devices[index]; - BLI_threadpool_insert(&g_work_scheduler.queue.threads, device); + for (Device &device : g_work_scheduler.queue.devices) { + BLI_threadpool_insert(&g_work_scheduler.queue.threads, &device); } } @@ -369,25 +359,17 @@ static void threading_model_queue_initialize(const int num_cpu_threads) { /* Reinitialize if number of threads doesn't match. */ if (g_work_scheduler.queue.devices.size() != num_cpu_threads) { - Device *device; - - while (!g_work_scheduler.queue.devices.is_empty()) { - device = g_work_scheduler.queue.devices.pop_last(); - device->deinitialize(); - delete device; - } + g_work_scheduler.queue.devices.clear(); if (g_work_scheduler.queue.initialized) { BLI_thread_local_delete(g_thread_device); + g_work_scheduler.queue.initialized = false; } - g_work_scheduler.queue.initialized = false; } /* Initialize CPU threads. */ if (!g_work_scheduler.queue.initialized) { for (int index = 0; index < num_cpu_threads; index++) { - CPUDevice *device = new CPUDevice(index); - device->initialize(); - g_work_scheduler.queue.devices.append(device); + g_work_scheduler.queue.devices.append(CPUDevice(index)); } BLI_thread_local_create(g_thread_device); g_work_scheduler.queue.initialized = true; @@ -397,12 +379,8 @@ static void threading_model_queue_deinitialize() { /* deinitialize CPU threads */ if (g_work_scheduler.queue.initialized) { - Device *device; - while (!g_work_scheduler.queue.devices.is_empty()) { - device = g_work_scheduler.queue.devices.pop_last(); - device->deinitialize(); - delete device; - } + g_work_scheduler.queue.devices.clear_and_make_inline(); + BLI_thread_local_delete(g_thread_device); g_work_scheduler.queue.initialized = false; } diff --git a/source/blender/compositor/nodes/COM_AlphaOverNode.h b/source/blender/compositor/nodes/COM_AlphaOverNode.h index 32cd2e20204..cbfda2885d7 100644 --- a/source/blender/compositor/nodes/COM_AlphaOverNode.h +++ b/source/blender/compositor/nodes/COM_AlphaOverNode.h @@ -29,5 +29,6 @@ class AlphaOverNode : public Node { AlphaOverNode(bNode *editorNode) : Node(editorNode) { } - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.h b/source/blender/compositor/nodes/COM_BilateralBlurNode.h index 39308c7d1b6..39abc47bfaa 100644 --- a/source/blender/compositor/nodes/COM_BilateralBlurNode.h +++ b/source/blender/compositor/nodes/COM_BilateralBlurNode.h @@ -27,5 +27,6 @@ class BilateralBlurNode : public Node { public: BilateralBlurNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_BlurNode.h b/source/blender/compositor/nodes/COM_BlurNode.h index 3c832c93ca2..6f756445ea2 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.h +++ b/source/blender/compositor/nodes/COM_BlurNode.h @@ -27,5 +27,6 @@ class BlurNode : public Node { public: BlurNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.h b/source/blender/compositor/nodes/COM_BokehBlurNode.h index 87aca9af1f6..3d73fc50dbc 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.h +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.h @@ -27,5 +27,6 @@ class BokehBlurNode : public Node { public: BokehBlurNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.h b/source/blender/compositor/nodes/COM_BokehImageNode.h index b9d957cd6df..0adb671ddc3 100644 --- a/source/blender/compositor/nodes/COM_BokehImageNode.h +++ b/source/blender/compositor/nodes/COM_BokehImageNode.h @@ -27,5 +27,6 @@ class BokehImageNode : public Node { public: BokehImageNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_BoxMaskNode.h b/source/blender/compositor/nodes/COM_BoxMaskNode.h index b815fd75284..572228d2684 100644 --- a/source/blender/compositor/nodes/COM_BoxMaskNode.h +++ b/source/blender/compositor/nodes/COM_BoxMaskNode.h @@ -27,5 +27,6 @@ class BoxMaskNode : public Node { public: BoxMaskNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.h b/source/blender/compositor/nodes/COM_BrightnessNode.h index b64b622dd71..4ae50e23798 100644 --- a/source/blender/compositor/nodes/COM_BrightnessNode.h +++ b/source/blender/compositor/nodes/COM_BrightnessNode.h @@ -27,5 +27,6 @@ class BrightnessNode : public Node { public: BrightnessNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.h b/source/blender/compositor/nodes/COM_ChannelMatteNode.h index bca821fa60c..f282ae81afc 100644 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.h @@ -27,5 +27,6 @@ class ChannelMatteNode : public Node { public: ChannelMatteNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.h b/source/blender/compositor/nodes/COM_ChromaMatteNode.h index d8febdde36f..196c69bfe9d 100644 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.h @@ -27,5 +27,6 @@ class ChromaMatteNode : public Node { public: ChromaMatteNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.h b/source/blender/compositor/nodes/COM_ColorBalanceNode.h index 302b66863ca..0391fbe25c3 100644 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.h +++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.h @@ -27,5 +27,6 @@ class ColorBalanceNode : public Node { public: ColorBalanceNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h index be6545f0cfa..35878dde32f 100644 --- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h +++ b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h @@ -27,5 +27,6 @@ class ColorCorrectionNode : public Node { public: ColorCorrectionNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.h b/source/blender/compositor/nodes/COM_ColorCurveNode.h index 6eaf1db6fbb..18806c00264 100644 --- a/source/blender/compositor/nodes/COM_ColorCurveNode.h +++ b/source/blender/compositor/nodes/COM_ColorCurveNode.h @@ -27,5 +27,6 @@ class ColorCurveNode : public Node { public: ColorCurveNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ColorExposureNode.h b/source/blender/compositor/nodes/COM_ColorExposureNode.h index c17e798b979..97fa9c97650 100644 --- a/source/blender/compositor/nodes/COM_ColorExposureNode.h +++ b/source/blender/compositor/nodes/COM_ColorExposureNode.h @@ -27,5 +27,6 @@ class ExposureNode : public Node { public: ExposureNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.h b/source/blender/compositor/nodes/COM_ColorMatteNode.h index e84bdfc836f..3f47d707d38 100644 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.h +++ b/source/blender/compositor/nodes/COM_ColorMatteNode.h @@ -27,5 +27,6 @@ class ColorMatteNode : public Node { public: ColorMatteNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ColorNode.h b/source/blender/compositor/nodes/COM_ColorNode.h index 9b50e9ab7d4..5df60dfbe1c 100644 --- a/source/blender/compositor/nodes/COM_ColorNode.h +++ b/source/blender/compositor/nodes/COM_ColorNode.h @@ -27,5 +27,6 @@ class ColorNode : public Node { public: ColorNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.h b/source/blender/compositor/nodes/COM_ColorRampNode.h index b53edf14dbd..81c3a2f78dc 100644 --- a/source/blender/compositor/nodes/COM_ColorRampNode.h +++ b/source/blender/compositor/nodes/COM_ColorRampNode.h @@ -27,5 +27,6 @@ class ColorRampNode : public Node { public: ColorRampNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.h b/source/blender/compositor/nodes/COM_ColorSpillNode.h index 3cf8072c7b7..3026f335ba6 100644 --- a/source/blender/compositor/nodes/COM_ColorSpillNode.h +++ b/source/blender/compositor/nodes/COM_ColorSpillNode.h @@ -27,5 +27,6 @@ class ColorSpillNode : public Node { public: ColorSpillNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ColorToBWNode.h b/source/blender/compositor/nodes/COM_ColorToBWNode.h index 6e7025de496..475563f0830 100644 --- a/source/blender/compositor/nodes/COM_ColorToBWNode.h +++ b/source/blender/compositor/nodes/COM_ColorToBWNode.h @@ -27,5 +27,6 @@ class ColorToBWNode : public Node { public: ColorToBWNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.h b/source/blender/compositor/nodes/COM_CombineColorNode.h index 378a4855abf..e6a8f5acfb7 100644 --- a/source/blender/compositor/nodes/COM_CombineColorNode.h +++ b/source/blender/compositor/nodes/COM_CombineColorNode.h @@ -23,7 +23,8 @@ class CombineColorNode : public Node { public: CombineColorNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; protected: virtual NodeOperation *getColorConverter(const CompositorContext &context) const = 0; @@ -35,7 +36,7 @@ class CombineRGBANode : public CombineColorNode { { } - NodeOperation *getColorConverter(const CompositorContext &context) const; + NodeOperation *getColorConverter(const CompositorContext &context) const override; }; class CombineHSVANode : public CombineColorNode { @@ -44,7 +45,7 @@ class CombineHSVANode : public CombineColorNode { { } - NodeOperation *getColorConverter(const CompositorContext &context) const; + NodeOperation *getColorConverter(const CompositorContext &context) const override; }; class CombineYCCANode : public CombineColorNode { @@ -53,7 +54,7 @@ class CombineYCCANode : public CombineColorNode { { } - NodeOperation *getColorConverter(const CompositorContext &context) const; + NodeOperation *getColorConverter(const CompositorContext &context) const override; }; class CombineYUVANode : public CombineColorNode { @@ -62,5 +63,5 @@ class CombineYUVANode : public CombineColorNode { { } - NodeOperation *getColorConverter(const CompositorContext &context) const; + NodeOperation *getColorConverter(const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_CompositorNode.h b/source/blender/compositor/nodes/COM_CompositorNode.h index a75355dfc14..488cfe88d24 100644 --- a/source/blender/compositor/nodes/COM_CompositorNode.h +++ b/source/blender/compositor/nodes/COM_CompositorNode.h @@ -27,5 +27,6 @@ class CompositorNode : public Node { public: CompositorNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h index 372f34a576f..45be8925ad2 100644 --- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h +++ b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h @@ -29,5 +29,6 @@ class ConvertAlphaNode : public Node { ConvertAlphaNode(bNode *editorNode) : Node(editorNode) { } - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_CornerPinNode.h b/source/blender/compositor/nodes/COM_CornerPinNode.h index ba845a614fb..5cbedcb7057 100644 --- a/source/blender/compositor/nodes/COM_CornerPinNode.h +++ b/source/blender/compositor/nodes/COM_CornerPinNode.h @@ -28,5 +28,6 @@ class CornerPinNode : public Node { public: CornerPinNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_CropNode.h b/source/blender/compositor/nodes/COM_CropNode.h index f643ebbabcc..54ada91a5cc 100644 --- a/source/blender/compositor/nodes/COM_CropNode.h +++ b/source/blender/compositor/nodes/COM_CropNode.h @@ -27,5 +27,6 @@ class CropNode : public Node { public: CropNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.h b/source/blender/compositor/nodes/COM_CryptomatteNode.h index e99a104c914..0ea05eb50f7 100644 --- a/source/blender/compositor/nodes/COM_CryptomatteNode.h +++ b/source/blender/compositor/nodes/COM_CryptomatteNode.h @@ -36,7 +36,8 @@ class CryptomatteBaseNode : public Node { } public: - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; protected: virtual CryptomatteOperation *create_cryptomatte_operation( diff --git a/source/blender/compositor/nodes/COM_DefocusNode.h b/source/blender/compositor/nodes/COM_DefocusNode.h index c042e98c515..447950c66dd 100644 --- a/source/blender/compositor/nodes/COM_DefocusNode.h +++ b/source/blender/compositor/nodes/COM_DefocusNode.h @@ -27,5 +27,6 @@ class DefocusNode : public Node { public: DefocusNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_DenoiseNode.h b/source/blender/compositor/nodes/COM_DenoiseNode.h index 99f59c89fdb..eb0857fe514 100644 --- a/source/blender/compositor/nodes/COM_DenoiseNode.h +++ b/source/blender/compositor/nodes/COM_DenoiseNode.h @@ -27,5 +27,6 @@ class DenoiseNode : public Node { public: DenoiseNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_DespeckleNode.h b/source/blender/compositor/nodes/COM_DespeckleNode.h index 6b39dd94ac7..47879bc3d3c 100644 --- a/source/blender/compositor/nodes/COM_DespeckleNode.h +++ b/source/blender/compositor/nodes/COM_DespeckleNode.h @@ -27,5 +27,6 @@ class DespeckleNode : public Node { public: DespeckleNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h index 26be5fe1e80..db149a02c07 100644 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h @@ -27,5 +27,6 @@ class DifferenceMatteNode : public Node { public: DifferenceMatteNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.h b/source/blender/compositor/nodes/COM_DilateErodeNode.h index 090095df447..78cc2d21a7a 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.h +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.h @@ -30,5 +30,6 @@ class DilateErodeNode : public Node { public: DilateErodeNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h index dfb705cbe64..2f64559e378 100644 --- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h +++ b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h @@ -27,5 +27,6 @@ class DirectionalBlurNode : public Node { public: DirectionalBlurNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_DisplaceNode.h b/source/blender/compositor/nodes/COM_DisplaceNode.h index a9e8a5ad657..5496d6833c1 100644 --- a/source/blender/compositor/nodes/COM_DisplaceNode.h +++ b/source/blender/compositor/nodes/COM_DisplaceNode.h @@ -27,5 +27,6 @@ class DisplaceNode : public Node { public: DisplaceNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.h b/source/blender/compositor/nodes/COM_DistanceMatteNode.h index 6ae71ef715f..c237edc4d2d 100644 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.h @@ -27,5 +27,6 @@ class DistanceMatteNode : public Node { public: DistanceMatteNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h index 6d26cbbf528..0244ba2cbe2 100644 --- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h +++ b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h @@ -27,5 +27,6 @@ class DoubleEdgeMaskNode : public Node { public: DoubleEdgeMaskNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_EllipseMaskNode.h b/source/blender/compositor/nodes/COM_EllipseMaskNode.h index d7376cad52e..87f2c498165 100644 --- a/source/blender/compositor/nodes/COM_EllipseMaskNode.h +++ b/source/blender/compositor/nodes/COM_EllipseMaskNode.h @@ -27,5 +27,6 @@ class EllipseMaskNode : public Node { public: EllipseMaskNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_FilterNode.h b/source/blender/compositor/nodes/COM_FilterNode.h index 735d8925b48..c86e65b5807 100644 --- a/source/blender/compositor/nodes/COM_FilterNode.h +++ b/source/blender/compositor/nodes/COM_FilterNode.h @@ -27,5 +27,6 @@ class FilterNode : public Node { public: FilterNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_FlipNode.h b/source/blender/compositor/nodes/COM_FlipNode.h index e819c003430..29fa904c4f6 100644 --- a/source/blender/compositor/nodes/COM_FlipNode.h +++ b/source/blender/compositor/nodes/COM_FlipNode.h @@ -27,5 +27,6 @@ class FlipNode : public Node { public: FlipNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_GammaNode.h b/source/blender/compositor/nodes/COM_GammaNode.h index 1a4d02af160..b3bf9b649b9 100644 --- a/source/blender/compositor/nodes/COM_GammaNode.h +++ b/source/blender/compositor/nodes/COM_GammaNode.h @@ -27,5 +27,6 @@ class GammaNode : public Node { public: GammaNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_GlareNode.h b/source/blender/compositor/nodes/COM_GlareNode.h index 7463af97306..dbc02656006 100644 --- a/source/blender/compositor/nodes/COM_GlareNode.h +++ b/source/blender/compositor/nodes/COM_GlareNode.h @@ -27,5 +27,6 @@ class GlareNode : public Node { public: GlareNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h index 01790c1a5fb..e7656d2296c 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h +++ b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h @@ -27,5 +27,6 @@ class HueSaturationValueCorrectNode : public Node { public: HueSaturationValueCorrectNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h index 7ef7abe4188..b35f6ae14b7 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h +++ b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h @@ -27,5 +27,6 @@ class HueSaturationValueNode : public Node { public: HueSaturationValueNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.h b/source/blender/compositor/nodes/COM_IDMaskNode.h index 51076619951..2766377e47a 100644 --- a/source/blender/compositor/nodes/COM_IDMaskNode.h +++ b/source/blender/compositor/nodes/COM_IDMaskNode.h @@ -27,5 +27,6 @@ class IDMaskNode : public Node { public: IDMaskNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ImageNode.h b/source/blender/compositor/nodes/COM_ImageNode.h index b99fc07f105..716687c91b4 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.h +++ b/source/blender/compositor/nodes/COM_ImageNode.h @@ -44,5 +44,6 @@ class ImageNode : public Node { public: ImageNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_InpaintNode.h b/source/blender/compositor/nodes/COM_InpaintNode.h index 3f778c8ba5c..864d8bbd5cd 100644 --- a/source/blender/compositor/nodes/COM_InpaintNode.h +++ b/source/blender/compositor/nodes/COM_InpaintNode.h @@ -27,5 +27,6 @@ class InpaintNode : public Node { public: InpaintNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_InvertNode.h b/source/blender/compositor/nodes/COM_InvertNode.h index d90d6e48713..ab5f80a5e87 100644 --- a/source/blender/compositor/nodes/COM_InvertNode.h +++ b/source/blender/compositor/nodes/COM_InvertNode.h @@ -27,5 +27,6 @@ class InvertNode : public Node { public: InvertNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h index 6920d2af09d..64eaaf2a537 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.h +++ b/source/blender/compositor/nodes/COM_KeyingNode.h @@ -55,5 +55,6 @@ class KeyingNode : public Node { public: KeyingNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.h b/source/blender/compositor/nodes/COM_KeyingScreenNode.h index ce9ef54543d..2c84b71773e 100644 --- a/source/blender/compositor/nodes/COM_KeyingScreenNode.h +++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.h @@ -28,5 +28,6 @@ class KeyingScreenNode : public Node { public: KeyingScreenNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.h b/source/blender/compositor/nodes/COM_LensDistortionNode.h index 8df0e3f7df1..866e2ec8884 100644 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.h +++ b/source/blender/compositor/nodes/COM_LensDistortionNode.h @@ -27,5 +27,6 @@ class LensDistortionNode : public Node { public: LensDistortionNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h index 7f2d9dfbe95..148a0d302d4 100644 --- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h @@ -27,5 +27,6 @@ class LuminanceMatteNode : public Node { public: LuminanceMatteNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.h b/source/blender/compositor/nodes/COM_MapRangeNode.h index b838ea858ee..55c7020635a 100644 --- a/source/blender/compositor/nodes/COM_MapRangeNode.h +++ b/source/blender/compositor/nodes/COM_MapRangeNode.h @@ -27,5 +27,6 @@ class MapRangeNode : public Node { public: MapRangeNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_MapUVNode.h b/source/blender/compositor/nodes/COM_MapUVNode.h index f9fc413dbe5..ff565372d71 100644 --- a/source/blender/compositor/nodes/COM_MapUVNode.h +++ b/source/blender/compositor/nodes/COM_MapUVNode.h @@ -27,5 +27,6 @@ class MapUVNode : public Node { public: MapUVNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_MapValueNode.h b/source/blender/compositor/nodes/COM_MapValueNode.h index 60ee262d447..a8a5028a71f 100644 --- a/source/blender/compositor/nodes/COM_MapValueNode.h +++ b/source/blender/compositor/nodes/COM_MapValueNode.h @@ -27,5 +27,6 @@ class MapValueNode : public Node { public: MapValueNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h index 4a03916b3c2..3d813fb61f2 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.h +++ b/source/blender/compositor/nodes/COM_MaskNode.h @@ -28,5 +28,6 @@ class MaskNode : public Node { public: MaskNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_MathNode.h b/source/blender/compositor/nodes/COM_MathNode.h index 41b144679ac..a7036e9fd36 100644 --- a/source/blender/compositor/nodes/COM_MathNode.h +++ b/source/blender/compositor/nodes/COM_MathNode.h @@ -29,5 +29,6 @@ class MathNode : public Node { MathNode(bNode *editorNode) : Node(editorNode) { } - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_MixNode.h b/source/blender/compositor/nodes/COM_MixNode.h index 91ce29fdbf2..6f4a7a2cb88 100644 --- a/source/blender/compositor/nodes/COM_MixNode.h +++ b/source/blender/compositor/nodes/COM_MixNode.h @@ -27,5 +27,6 @@ class MixNode : public Node { public: MixNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.h b/source/blender/compositor/nodes/COM_MovieClipNode.h index 58262592dca..c46033f944a 100644 --- a/source/blender/compositor/nodes/COM_MovieClipNode.h +++ b/source/blender/compositor/nodes/COM_MovieClipNode.h @@ -28,5 +28,6 @@ class MovieClipNode : public Node { public: MovieClipNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_MovieDistortionNode.h b/source/blender/compositor/nodes/COM_MovieDistortionNode.h index f4df48dac13..60349be0793 100644 --- a/source/blender/compositor/nodes/COM_MovieDistortionNode.h +++ b/source/blender/compositor/nodes/COM_MovieDistortionNode.h @@ -27,5 +27,6 @@ class MovieDistortionNode : public Node { public: MovieDistortionNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_NormalNode.h b/source/blender/compositor/nodes/COM_NormalNode.h index c23e83fb023..9b32e57a141 100644 --- a/source/blender/compositor/nodes/COM_NormalNode.h +++ b/source/blender/compositor/nodes/COM_NormalNode.h @@ -27,5 +27,6 @@ class NormalNode : public Node { public: NormalNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_NormalizeNode.h b/source/blender/compositor/nodes/COM_NormalizeNode.h index 7e53ac7e9a0..bf8055245e7 100644 --- a/source/blender/compositor/nodes/COM_NormalizeNode.h +++ b/source/blender/compositor/nodes/COM_NormalizeNode.h @@ -27,5 +27,6 @@ class NormalizeNode : public Node { public: NormalizeNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.h b/source/blender/compositor/nodes/COM_OutputFileNode.h index 037a345fa50..2b37a1ae252 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.h +++ b/source/blender/compositor/nodes/COM_OutputFileNode.h @@ -28,5 +28,6 @@ class OutputFileNode : public Node { public: OutputFileNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_PixelateNode.h b/source/blender/compositor/nodes/COM_PixelateNode.h index 87cb4df59e8..19ae352ce80 100644 --- a/source/blender/compositor/nodes/COM_PixelateNode.h +++ b/source/blender/compositor/nodes/COM_PixelateNode.h @@ -27,5 +27,6 @@ class PixelateNode : public Node { public: PixelateNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h index 36844bc1650..29347ec79c4 100644 --- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h +++ b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h @@ -30,5 +30,6 @@ class PlaneTrackDeformNode : public Node { public: PlaneTrackDeformNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.h b/source/blender/compositor/nodes/COM_RenderLayersNode.h index 1ffd084ad1e..92be0f7daa1 100644 --- a/source/blender/compositor/nodes/COM_RenderLayersNode.h +++ b/source/blender/compositor/nodes/COM_RenderLayersNode.h @@ -31,7 +31,8 @@ struct Render; class RenderLayersNode : public Node { public: RenderLayersNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; private: void testSocketLink(NodeConverter &converter, diff --git a/source/blender/compositor/nodes/COM_RotateNode.h b/source/blender/compositor/nodes/COM_RotateNode.h index b75fdd52683..0f3b6497cb7 100644 --- a/source/blender/compositor/nodes/COM_RotateNode.h +++ b/source/blender/compositor/nodes/COM_RotateNode.h @@ -27,5 +27,6 @@ class RotateNode : public Node { public: RotateNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ScaleNode.h b/source/blender/compositor/nodes/COM_ScaleNode.h index c9a02411b1c..5babec2b7aa 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.h +++ b/source/blender/compositor/nodes/COM_ScaleNode.h @@ -27,5 +27,6 @@ class ScaleNode : public Node { public: ScaleNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.h b/source/blender/compositor/nodes/COM_SeparateColorNode.h index aaf86c6e22b..4772c62f93c 100644 --- a/source/blender/compositor/nodes/COM_SeparateColorNode.h +++ b/source/blender/compositor/nodes/COM_SeparateColorNode.h @@ -23,7 +23,8 @@ class SeparateColorNode : public Node { public: SeparateColorNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; protected: virtual NodeOperation *getColorConverter(const CompositorContext &context) const = 0; @@ -35,7 +36,7 @@ class SeparateRGBANode : public SeparateColorNode { { } - NodeOperation *getColorConverter(const CompositorContext &context) const; + NodeOperation *getColorConverter(const CompositorContext &context) const override; }; class SeparateHSVANode : public SeparateColorNode { @@ -44,7 +45,7 @@ class SeparateHSVANode : public SeparateColorNode { { } - NodeOperation *getColorConverter(const CompositorContext &context) const; + NodeOperation *getColorConverter(const CompositorContext &context) const override; }; class SeparateYCCANode : public SeparateColorNode { @@ -53,7 +54,7 @@ class SeparateYCCANode : public SeparateColorNode { { } - NodeOperation *getColorConverter(const CompositorContext &context) const; + NodeOperation *getColorConverter(const CompositorContext &context) const override; }; class SeparateYUVANode : public SeparateColorNode { @@ -62,5 +63,5 @@ class SeparateYUVANode : public SeparateColorNode { { } - NodeOperation *getColorConverter(const CompositorContext &context) const; + NodeOperation *getColorConverter(const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.h b/source/blender/compositor/nodes/COM_SetAlphaNode.h index 2e652539cec..06dd93012ff 100644 --- a/source/blender/compositor/nodes/COM_SetAlphaNode.h +++ b/source/blender/compositor/nodes/COM_SetAlphaNode.h @@ -29,5 +29,6 @@ class SetAlphaNode : public Node { SetAlphaNode(bNode *editorNode) : Node(editorNode) { } - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.h b/source/blender/compositor/nodes/COM_SocketProxyNode.h index a0c0b63dafd..8616fe6dccf 100644 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.h +++ b/source/blender/compositor/nodes/COM_SocketProxyNode.h @@ -30,7 +30,8 @@ class SocketProxyNode : public Node { bNodeSocket *editorInput, bNodeSocket *editorOutput, bool use_conversion); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; bool getUseConversion() const { @@ -49,5 +50,6 @@ class SocketProxyNode : public Node { class SocketBufferNode : public Node { public: SocketBufferNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.h b/source/blender/compositor/nodes/COM_SplitViewerNode.h index c9ce5164ef4..0be586041e9 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.h +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.h @@ -27,5 +27,6 @@ class SplitViewerNode : public Node { public: SplitViewerNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_Stabilize2dNode.h b/source/blender/compositor/nodes/COM_Stabilize2dNode.h index cb46926a3f3..2c7cfafb297 100644 --- a/source/blender/compositor/nodes/COM_Stabilize2dNode.h +++ b/source/blender/compositor/nodes/COM_Stabilize2dNode.h @@ -28,5 +28,6 @@ class Stabilize2dNode : public Node { public: Stabilize2dNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_SunBeamsNode.h b/source/blender/compositor/nodes/COM_SunBeamsNode.h index 9a56fc1fcea..8b02f13211f 100644 --- a/source/blender/compositor/nodes/COM_SunBeamsNode.h +++ b/source/blender/compositor/nodes/COM_SunBeamsNode.h @@ -26,5 +26,6 @@ class SunBeamsNode : public Node { public: SunBeamsNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_SwitchNode.h b/source/blender/compositor/nodes/COM_SwitchNode.h index d4d8dd23a98..c8ee503154c 100644 --- a/source/blender/compositor/nodes/COM_SwitchNode.h +++ b/source/blender/compositor/nodes/COM_SwitchNode.h @@ -28,5 +28,6 @@ class SwitchNode : public Node { public: SwitchNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_SwitchViewNode.h b/source/blender/compositor/nodes/COM_SwitchViewNode.h index 9423740f668..419fd1b7463 100644 --- a/source/blender/compositor/nodes/COM_SwitchViewNode.h +++ b/source/blender/compositor/nodes/COM_SwitchViewNode.h @@ -28,5 +28,6 @@ class SwitchViewNode : public Node { public: SwitchViewNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_TextureNode.h b/source/blender/compositor/nodes/COM_TextureNode.h index 4d780850190..5a9a56b748d 100644 --- a/source/blender/compositor/nodes/COM_TextureNode.h +++ b/source/blender/compositor/nodes/COM_TextureNode.h @@ -28,5 +28,6 @@ class TextureNode : public Node { public: TextureNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_TimeNode.h b/source/blender/compositor/nodes/COM_TimeNode.h index 78177014dc1..0f2b624fd1f 100644 --- a/source/blender/compositor/nodes/COM_TimeNode.h +++ b/source/blender/compositor/nodes/COM_TimeNode.h @@ -27,5 +27,6 @@ class TimeNode : public Node { public: TimeNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_TonemapNode.h b/source/blender/compositor/nodes/COM_TonemapNode.h index d934a1ede5b..db7ae5fa290 100644 --- a/source/blender/compositor/nodes/COM_TonemapNode.h +++ b/source/blender/compositor/nodes/COM_TonemapNode.h @@ -27,5 +27,6 @@ class TonemapNode : public Node { public: TonemapNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_TrackPositionNode.h b/source/blender/compositor/nodes/COM_TrackPositionNode.h index 37d3d25d592..f2062828ca5 100644 --- a/source/blender/compositor/nodes/COM_TrackPositionNode.h +++ b/source/blender/compositor/nodes/COM_TrackPositionNode.h @@ -28,5 +28,6 @@ class TrackPositionNode : public Node { public: TrackPositionNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_TransformNode.h b/source/blender/compositor/nodes/COM_TransformNode.h index bd01808d662..56d05cd4c94 100644 --- a/source/blender/compositor/nodes/COM_TransformNode.h +++ b/source/blender/compositor/nodes/COM_TransformNode.h @@ -28,5 +28,6 @@ class TransformNode : public Node { public: TransformNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_TranslateNode.h b/source/blender/compositor/nodes/COM_TranslateNode.h index d381274c0e5..e6fd230572c 100644 --- a/source/blender/compositor/nodes/COM_TranslateNode.h +++ b/source/blender/compositor/nodes/COM_TranslateNode.h @@ -27,5 +27,6 @@ class TranslateNode : public Node { public: TranslateNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ValueNode.h b/source/blender/compositor/nodes/COM_ValueNode.h index 5179e6828e4..18162b7d4b8 100644 --- a/source/blender/compositor/nodes/COM_ValueNode.h +++ b/source/blender/compositor/nodes/COM_ValueNode.h @@ -27,5 +27,6 @@ class ValueNode : public Node { public: ValueNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.h b/source/blender/compositor/nodes/COM_VectorBlurNode.h index f370c82a1ee..2a55ca4457d 100644 --- a/source/blender/compositor/nodes/COM_VectorBlurNode.h +++ b/source/blender/compositor/nodes/COM_VectorBlurNode.h @@ -27,5 +27,6 @@ class VectorBlurNode : public Node { public: VectorBlurNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.h b/source/blender/compositor/nodes/COM_VectorCurveNode.h index 4d7f92897a1..4e84b7454d9 100644 --- a/source/blender/compositor/nodes/COM_VectorCurveNode.h +++ b/source/blender/compositor/nodes/COM_VectorCurveNode.h @@ -27,5 +27,6 @@ class VectorCurveNode : public Node { public: VectorCurveNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.h b/source/blender/compositor/nodes/COM_ViewLevelsNode.h index 0e931fed055..20dbe967286 100644 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.h +++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.h @@ -27,5 +27,6 @@ class ViewLevelsNode : public Node { public: ViewLevelsNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ViewerNode.h b/source/blender/compositor/nodes/COM_ViewerNode.h index 74758417014..0e13f165794 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.h +++ b/source/blender/compositor/nodes/COM_ViewerNode.h @@ -27,5 +27,6 @@ class ViewerNode : public Node { public: ViewerNode(bNode *editorNode); - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.h b/source/blender/compositor/nodes/COM_ZCombineNode.h index ca54fd7fffa..aa8bd979691 100644 --- a/source/blender/compositor/nodes/COM_ZCombineNode.h +++ b/source/blender/compositor/nodes/COM_ZCombineNode.h @@ -29,5 +29,6 @@ class ZCombineNode : public Node { ZCombineNode(bNode *editorNode) : Node(editorNode) { } - void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; + void convertToOperations(NodeConverter &converter, + const CompositorContext &context) const override; }; diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h index f2ec5ff12c2..b62105d7c41 100644 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h @@ -34,5 +34,5 @@ class AlphaOverKeyOperation : public MixBaseOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h index 73433ec3077..3f7137a8d36 100644 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h @@ -37,7 +37,7 @@ class AlphaOverMixedOperation : public MixBaseOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; void setX(float x) { diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h index b149789878e..cb60f8393d0 100644 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h @@ -34,5 +34,5 @@ class AlphaOverPremultiplyOperation : public MixBaseOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.h b/source/blender/compositor/operations/COM_AntiAliasOperation.h index 571655813ae..691fb970b11 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.h +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.h @@ -39,20 +39,20 @@ class AntiAliasOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.h b/source/blender/compositor/operations/COM_BilateralBlurOperation.h index d059510f0bc..bdc77325aaf 100644 --- a/source/blender/compositor/operations/COM_BilateralBlurOperation.h +++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.h @@ -34,21 +34,21 @@ class BilateralBlurOperation : public NodeOperation, public QualityStepHelper { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void setData(NodeBilateralBlurData *data) { diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h index 56dacc96710..84f94dfe124 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.h +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h @@ -53,12 +53,12 @@ class BlurBaseOperation : public NodeOperation, public QualityStepHelper { /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setData(const NodeBlurData *data); @@ -73,5 +73,6 @@ class BlurBaseOperation : public NodeOperation, public QualityStepHelper { this->m_extend_bounds = extend_bounds; } - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; }; diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.h b/source/blender/compositor/operations/COM_BokehBlurOperation.h index a2e320dfdad..9bdf8bc4035 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.h @@ -37,25 +37,25 @@ class BokehBlurOperation : public NodeOperation, public QualityStepHelper { public: BokehBlurOperation(); - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void setSize(float size) { @@ -68,12 +68,13 @@ class BokehBlurOperation : public NodeOperation, public QualityStepHelper { cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, std::list<cl_mem> *clMemToCleanUp, - std::list<cl_kernel> *clKernelsToCleanUp); + std::list<cl_kernel> *clKernelsToCleanUp) override; void setExtendBounds(bool extend_bounds) { this->m_extend_bounds = extend_bounds; } - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; }; diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.h b/source/blender/compositor/operations/COM_BokehImageOperation.h index 2d775bdf738..34fd4f6411b 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.h +++ b/source/blender/compositor/operations/COM_BokehImageOperation.h @@ -110,23 +110,24 @@ class BokehImageOperation : public NodeOperation { /** * \brief The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * \brief Initialize the execution */ - void initExecution(); + void initExecution() override; /** * \brief Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; /** * \brief determine the resolution of this operation. currently fixed at [COM_BLUR_BOKEH_PIXELS, * COM_BLUR_BOKEH_PIXELS] \param resolution: \param preferredResolution: */ - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; /** * \brief set the node data diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.h b/source/blender/compositor/operations/COM_BoxMaskOperation.h index c98972b82b7..6ffa7d98aff 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.h +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.h @@ -41,17 +41,17 @@ class BoxMaskOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setData(NodeBoxMask *data) { diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.h b/source/blender/compositor/operations/COM_BrightnessOperation.h index 6fbcfe3a17a..fa2c80ab3f1 100644 --- a/source/blender/compositor/operations/COM_BrightnessOperation.h +++ b/source/blender/compositor/operations/COM_BrightnessOperation.h @@ -37,17 +37,17 @@ class BrightnessOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setUsePremultiply(bool use_premultiply); }; diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.h b/source/blender/compositor/operations/COM_CalculateMeanOperation.h index e4937931df0..e1a5bc3fd75 100644 --- a/source/blender/compositor/operations/COM_CalculateMeanOperation.h +++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.h @@ -42,23 +42,23 @@ class CalculateMeanOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void setSetting(int setting) { this->m_setting = setting; diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h index a267663cfc8..f377f96418a 100644 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h @@ -36,7 +36,7 @@ class CalculateStandardDeviationOperation : public CalculateMeanOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; }; diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.h b/source/blender/compositor/operations/COM_ChangeHSVOperation.h index edc532a3f43..f448956df16 100644 --- a/source/blender/compositor/operations/COM_ChangeHSVOperation.h +++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.h @@ -37,11 +37,11 @@ class ChangeHSVOperation : public NodeOperation { */ ChangeHSVOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.h b/source/blender/compositor/operations/COM_ChannelMatteOperation.h index 9a0b888b5a2..b295f7709d6 100644 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.h +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.h @@ -56,10 +56,10 @@ class ChannelMatteOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setSettings(NodeChroma *nodeChroma, const int custom2) { diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.h b/source/blender/compositor/operations/COM_ChromaMatteOperation.h index c8d261284ed..11f8c540a4b 100644 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.h +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.h @@ -39,10 +39,10 @@ class ChromaMatteOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setSettings(NodeChroma *nodeChroma) { diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h index 1ec920cb2da..b7ee5d341ad 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h @@ -45,17 +45,17 @@ class ColorBalanceASCCDLOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setOffset(float offset[3]) { diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h index e6acd16e4f0..4b2db3da134 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h @@ -45,17 +45,17 @@ class ColorBalanceLGGOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setGain(const float gain[3]) { diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h index 9a2e60c0d77..be0c9c198cf 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h @@ -39,17 +39,17 @@ class ColorCorrectionOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setData(NodeColorCorrection *data) { diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.h b/source/blender/compositor/operations/COM_ColorCurveOperation.h index 2eb20148db9..d57ff81bbe7 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.h +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.h @@ -38,17 +38,17 @@ class ColorCurveOperation : public CurveBaseOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; }; class ConstantLevelColorCurveOperation : public CurveBaseOperation { @@ -67,17 +67,17 @@ class ConstantLevelColorCurveOperation : public CurveBaseOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setBlackLevel(float black[3]) { diff --git a/source/blender/compositor/operations/COM_ColorExposureOperation.h b/source/blender/compositor/operations/COM_ColorExposureOperation.h index 97590b85d77..981caeb2663 100644 --- a/source/blender/compositor/operations/COM_ColorExposureOperation.h +++ b/source/blender/compositor/operations/COM_ColorExposureOperation.h @@ -34,15 +34,15 @@ class ExposureOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.h b/source/blender/compositor/operations/COM_ColorMatteOperation.h index 91ba27ce2b6..643dc83b3d9 100644 --- a/source/blender/compositor/operations/COM_ColorMatteOperation.h +++ b/source/blender/compositor/operations/COM_ColorMatteOperation.h @@ -39,10 +39,10 @@ class ColorMatteOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setSettings(NodeChroma *nodeChroma) { diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.h b/source/blender/compositor/operations/COM_ColorRampOperation.h index 49bdb266ce9..8e725ccf709 100644 --- a/source/blender/compositor/operations/COM_ColorRampOperation.h +++ b/source/blender/compositor/operations/COM_ColorRampOperation.h @@ -35,17 +35,17 @@ class ColorRampOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setColorBand(ColorBand *colorBand) { diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.h b/source/blender/compositor/operations/COM_ColorSpillOperation.h index e51101adf84..e8cd15fb3bc 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.h +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.h @@ -44,10 +44,10 @@ class ColorSpillOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setSettings(NodeColorspill *nodeColorSpill) { diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h index 63b87563852..1c964a80093 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.h +++ b/source/blender/compositor/operations/COM_CompositorOperation.h @@ -86,7 +86,7 @@ class CompositorOperation : public NodeOperation { { return this->m_active; } - void executeRegion(rcti *rect, unsigned int tileNumber); + void executeRegion(rcti *rect, unsigned int tileNumber) override; void setScene(const struct Scene *scene) { m_scene = scene; @@ -103,17 +103,18 @@ class CompositorOperation : public NodeOperation { { this->m_rd = rd; } - bool isOutputOperation(bool /*rendering*/) const + bool isOutputOperation(bool /*rendering*/) const override { return this->isActiveCompositorOutput(); } - void initExecution(); - void deinitExecution(); - CompositorPriority getRenderPriority() const + void initExecution() override; + void deinitExecution() override; + CompositorPriority getRenderPriority() const override { return CompositorPriority::Medium; } - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; void setUseAlphaInput(bool value) { this->m_useAlphaInput = value; diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h index 7b96895d845..927a5a7fef1 100644 --- a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h +++ b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h @@ -55,17 +55,17 @@ class ConvertColorProfileOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setFromColorProfile(int colorProfile) { diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h index 564a0facec7..6a7cc4e004a 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h @@ -51,17 +51,17 @@ class ConvertDepthToRadiusOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setfStop(float fStop) { diff --git a/source/blender/compositor/operations/COM_ConvertOperation.h b/source/blender/compositor/operations/COM_ConvertOperation.h index ca026528a38..7e359a30d6c 100644 --- a/source/blender/compositor/operations/COM_ConvertOperation.h +++ b/source/blender/compositor/operations/COM_ConvertOperation.h @@ -27,57 +27,57 @@ class ConvertBaseOperation : public NodeOperation { public: ConvertBaseOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; }; class ConvertValueToColorOperation : public ConvertBaseOperation { public: ConvertValueToColorOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertColorToValueOperation : public ConvertBaseOperation { public: ConvertColorToValueOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertColorToBWOperation : public ConvertBaseOperation { public: ConvertColorToBWOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertColorToVectorOperation : public ConvertBaseOperation { public: ConvertColorToVectorOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertValueToVectorOperation : public ConvertBaseOperation { public: ConvertValueToVectorOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertVectorToColorOperation : public ConvertBaseOperation { public: ConvertVectorToColorOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertVectorToValueOperation : public ConvertBaseOperation { public: ConvertVectorToValueOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertRGBToYCCOperation : public ConvertBaseOperation { @@ -88,7 +88,7 @@ class ConvertRGBToYCCOperation : public ConvertBaseOperation { public: ConvertRGBToYCCOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** Set the YCC mode */ void setMode(int mode); @@ -102,7 +102,7 @@ class ConvertYCCToRGBOperation : public ConvertBaseOperation { public: ConvertYCCToRGBOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** Set the YCC mode */ void setMode(int mode); @@ -112,42 +112,42 @@ class ConvertRGBToYUVOperation : public ConvertBaseOperation { public: ConvertRGBToYUVOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertYUVToRGBOperation : public ConvertBaseOperation { public: ConvertYUVToRGBOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertRGBToHSVOperation : public ConvertBaseOperation { public: ConvertRGBToHSVOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertHSVToRGBOperation : public ConvertBaseOperation { public: ConvertHSVToRGBOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertPremulToStraightOperation : public ConvertBaseOperation { public: ConvertPremulToStraightOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ConvertStraightToPremulOperation : public ConvertBaseOperation { public: ConvertStraightToPremulOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class SeparateChannelOperation : public NodeOperation { @@ -157,10 +157,10 @@ class SeparateChannelOperation : public NodeOperation { public: SeparateChannelOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setChannel(int channel) { @@ -177,8 +177,8 @@ class CombineChannelsOperation : public NodeOperation { public: CombineChannelsOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h index ab4b8a1dad1..4ee72ffdd97 100644 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h @@ -23,5 +23,5 @@ class ConvolutionEdgeFilterOperation : public ConvolutionFilterOperation { public: ConvolutionEdgeFilterOperation(); - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; }; diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h index d178b0a7418..08353fecca3 100644 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h @@ -36,9 +36,9 @@ class ConvolutionFilterOperation : public NodeOperation { float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void executePixel(float output[4], int x, int y, void *data); + rcti *output) override; + void executePixel(float output[4], int x, int y, void *data) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_CropOperation.h b/source/blender/compositor/operations/COM_CropOperation.h index f20664f0501..d2b9aee0bf3 100644 --- a/source/blender/compositor/operations/COM_CropOperation.h +++ b/source/blender/compositor/operations/COM_CropOperation.h @@ -34,8 +34,8 @@ class CropBaseOperation : public NodeOperation { public: CropBaseOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setCropSettings(NodeTwoXYs *settings) { this->m_settings = settings; @@ -50,7 +50,7 @@ class CropOperation : public CropBaseOperation { private: public: CropOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class CropImageOperation : public CropBaseOperation { @@ -59,7 +59,8 @@ class CropImageOperation : public CropBaseOperation { CropImageOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + rcti *output) override; + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.h b/source/blender/compositor/operations/COM_CryptomatteOperation.h index 8c5a3134720..a9cef7fe24b 100644 --- a/source/blender/compositor/operations/COM_CryptomatteOperation.h +++ b/source/blender/compositor/operations/COM_CryptomatteOperation.h @@ -29,8 +29,8 @@ class CryptomatteOperation : public NodeOperation { CryptomatteOperation(size_t num_inputs = 6); - void initExecution(); - void executePixel(float output[4], int x, int y, void *data); + void initExecution() override; + void executePixel(float output[4], int x, int y, void *data) override; void addObjectIndex(float objectIndex); }; diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.h b/source/blender/compositor/operations/COM_CurveBaseOperation.h index 63e667cfe12..15e484f4762 100644 --- a/source/blender/compositor/operations/COM_CurveBaseOperation.h +++ b/source/blender/compositor/operations/COM_CurveBaseOperation.h @@ -35,8 +35,8 @@ class CurveBaseOperation : public NodeOperation { /** * Initialize the execution */ - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setCurveMapping(CurveMapping *mapping); }; diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.h b/source/blender/compositor/operations/COM_DenoiseOperation.h index 5af6e16c958..162fe70617f 100644 --- a/source/blender/compositor/operations/COM_DenoiseOperation.h +++ b/source/blender/compositor/operations/COM_DenoiseOperation.h @@ -40,12 +40,12 @@ class DenoiseOperation : public SingleThreadedOperation { /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setDenoiseSettings(NodeDenoise *settings) { @@ -53,7 +53,7 @@ class DenoiseOperation : public SingleThreadedOperation { } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; protected: void generateDenoise(float *data, @@ -62,5 +62,5 @@ class DenoiseOperation : public SingleThreadedOperation { MemoryBuffer *inputTileAlbedo, NodeDenoise *settings); - MemoryBuffer *createMemoryBuffer(rcti *rect); + MemoryBuffer *createMemoryBuffer(rcti *rect) override; }; diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.h b/source/blender/compositor/operations/COM_DespeckleOperation.h index af37c276bd2..dee355696af 100644 --- a/source/blender/compositor/operations/COM_DespeckleOperation.h +++ b/source/blender/compositor/operations/COM_DespeckleOperation.h @@ -36,8 +36,8 @@ class DespeckleOperation : public NodeOperation { DespeckleOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void executePixel(float output[4], int x, int y, void *data); + rcti *output) override; + void executePixel(float output[4], int x, int y, void *data) override; void setThreshold(float threshold) { @@ -48,6 +48,6 @@ class DespeckleOperation : public NodeOperation { this->m_threshold_neighbor = threshold; } - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h index 0ee5eab3fe7..ded819850f8 100644 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h @@ -39,10 +39,10 @@ class DifferenceMatteOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setSettings(NodeChroma *nodeChroma) { diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h index 35f9be89220..7497fb8ab08 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.h +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h @@ -43,18 +43,18 @@ class DilateErodeThresholdOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setDistance(float distance) { @@ -71,7 +71,7 @@ class DilateErodeThresholdOperation : public NodeOperation { bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; class DilateDistanceOperation : public NodeOperation { @@ -90,18 +90,18 @@ class DilateDistanceOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setDistance(float distance) { @@ -109,14 +109,14 @@ class DilateDistanceOperation : public NodeOperation { } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, std::list<cl_mem> *clMemToCleanUp, - std::list<cl_kernel> *clKernelsToCleanUp); + std::list<cl_kernel> *clKernelsToCleanUp) override; }; class ErodeDistanceOperation : public DilateDistanceOperation { public: @@ -125,14 +125,14 @@ class ErodeDistanceOperation : public DilateDistanceOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, std::list<cl_mem> *clMemToCleanUp, - std::list<cl_kernel> *clKernelsToCleanUp); + std::list<cl_kernel> *clKernelsToCleanUp) override; }; class DilateStepOperation : public NodeOperation { @@ -150,19 +150,19 @@ class DilateStepOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; /** * Deinitialize the execution */ - void deinitExecution(); - void deinitializeTileData(rcti *rect, void *data); + void deinitExecution() override; + void deinitializeTileData(rcti *rect, void *data) override; void setIterations(int iterations) { @@ -171,12 +171,12 @@ class DilateStepOperation : public NodeOperation { bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; class ErodeStepOperation : public DilateStepOperation { public: ErodeStepOperation(); - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; }; diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h index 0c220f0e239..daf6bc75254 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h @@ -36,21 +36,21 @@ class DirectionalBlurOperation : public NodeOperation, public QualityStepHelper /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void setData(NodeDBlurData *data) { @@ -62,5 +62,5 @@ class DirectionalBlurOperation : public NodeOperation, public QualityStepHelper cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, std::list<cl_mem> *clMemToCleanUp, - std::list<cl_kernel> *clKernelsToCleanUp); + std::list<cl_kernel> *clKernelsToCleanUp) override; }; diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.h b/source/blender/compositor/operations/COM_DisplaceOperation.h index 52874779f73..368ed29ff0b 100644 --- a/source/blender/compositor/operations/COM_DisplaceOperation.h +++ b/source/blender/compositor/operations/COM_DisplaceOperation.h @@ -41,24 +41,24 @@ class DisplaceOperation : public NodeOperation { */ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; void pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2]); /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; private: bool read_displacement( diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h index 3b850d94750..63fe569c812 100644 --- a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h +++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h @@ -41,20 +41,20 @@ class DisplaceSimpleOperation : public NodeOperation { */ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h index 5c8c2204637..0593dc6b976 100644 --- a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h +++ b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h @@ -41,10 +41,10 @@ class DistanceRGBMatteOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setSettings(NodeChroma *nodeChroma) { diff --git a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h index e9b2cda6251..ce91e3a62ba 100644 --- a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h +++ b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h @@ -27,7 +27,7 @@ */ class DistanceYCCMatteOperation : public DistanceRGBMatteOperation { protected: - virtual float calculateDistance(float key[4], float image[4]); + float calculateDistance(float key[4], float image[4]) override; public: /** diff --git a/source/blender/compositor/operations/COM_DotproductOperation.h b/source/blender/compositor/operations/COM_DotproductOperation.h index 63b735ce30f..deff3ae5896 100644 --- a/source/blender/compositor/operations/COM_DotproductOperation.h +++ b/source/blender/compositor/operations/COM_DotproductOperation.h @@ -27,8 +27,8 @@ class DotproductOperation : public NodeOperation { public: DotproductOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h index 813f5009815..228c8edc53e 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h @@ -38,23 +38,23 @@ class DoubleEdgeMaskOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void setAdjecentOnly(bool adjacentOnly) { diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.h b/source/blender/compositor/operations/COM_EllipseMaskOperation.h index 8fce7166900..c7d7336600d 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.h +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.h @@ -41,17 +41,17 @@ class EllipseMaskOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setData(NodeEllipseMask *data) { diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h index 6ab6474c20a..c710baaaff8 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h @@ -31,13 +31,13 @@ class FastGaussianBlurOperation : public BlurBaseOperation { FastGaussianBlurOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void executePixel(float output[4], int x, int y, void *data); + rcti *output) override; + void executePixel(float output[4], int x, int y, void *data) override; static void IIR_gauss(MemoryBuffer *src, float sigma, unsigned int channel, unsigned int xy); - void *initializeTileData(rcti *rect); - void deinitExecution(); - void initExecution(); + void *initializeTileData(rcti *rect) override; + void deinitExecution() override; + void initExecution() override; }; enum { @@ -62,12 +62,12 @@ class FastGaussianBlurValueOperation : public NodeOperation { FastGaussianBlurValueOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void executePixel(float output[4], int x, int y, void *data); + rcti *output) override; + void executePixel(float output[4], int x, int y, void *data) override; - void *initializeTileData(rcti *rect); - void deinitExecution(); - void initExecution(); + void *initializeTileData(rcti *rect) override; + void deinitExecution() override; + void initExecution() override; void setSigma(float sigma) { this->m_sigma = sigma; diff --git a/source/blender/compositor/operations/COM_FlipOperation.h b/source/blender/compositor/operations/COM_FlipOperation.h index 711b51261e6..e571e57913f 100644 --- a/source/blender/compositor/operations/COM_FlipOperation.h +++ b/source/blender/compositor/operations/COM_FlipOperation.h @@ -30,11 +30,11 @@ class FlipOperation : public NodeOperation { FlipOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + rcti *output) override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setFlipX(bool flipX) { this->m_flipX = flipX; diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.h b/source/blender/compositor/operations/COM_GammaCorrectOperation.h index 077493bbd2f..81724581f55 100644 --- a/source/blender/compositor/operations/COM_GammaCorrectOperation.h +++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.h @@ -33,17 +33,17 @@ class GammaCorrectOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; }; class GammaUncorrectOperation : public NodeOperation { @@ -59,15 +59,15 @@ class GammaUncorrectOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_GammaOperation.h b/source/blender/compositor/operations/COM_GammaOperation.h index 8641f2fde62..c18f3bc3688 100644 --- a/source/blender/compositor/operations/COM_GammaOperation.h +++ b/source/blender/compositor/operations/COM_GammaOperation.h @@ -34,15 +34,15 @@ class GammaOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h index 2d536a98bee..51ca8359067 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h @@ -36,22 +36,22 @@ class GaussianAlphaXBlurOperation : public BlurBaseOperation { /** * \brief The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * \brief initialize the execution */ - void initExecution(); + void initExecution() override; /** * \brief Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; /** * Set subtract for Dilate/Erode functionality diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h index 7f1dfd78e7c..edd60acf2fc 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h @@ -36,22 +36,22 @@ class GaussianAlphaYBlurOperation : public BlurBaseOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * \brief initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; /** * Set subtract for Dilate/Erode functionality diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h index a37a70b4b33..0eb8379dfc8 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h @@ -30,21 +30,21 @@ class GaussianBokehBlurOperation : public BlurBaseOperation { public: GaussianBokehBlurOperation(); - void initExecution(); - void *initializeTileData(rcti *rect); + void initExecution() override; + void *initializeTileData(rcti *rect) override; /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; class GaussianBlurReferenceOperation : public BlurBaseOperation { @@ -59,19 +59,19 @@ class GaussianBlurReferenceOperation : public BlurBaseOperation { public: GaussianBlurReferenceOperation(); - void initExecution(); - void *initializeTileData(rcti *rect); + void initExecution() override; + void *initializeTileData(rcti *rect) override; /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h index 78ea6aa3cc2..44e6044e59b 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h @@ -36,29 +36,29 @@ class GaussianXBlurOperation : public BlurBaseOperation { /** * \brief The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, std::list<cl_mem> *clMemToCleanUp, - std::list<cl_kernel> *clKernelsToCleanUp); + std::list<cl_kernel> *clKernelsToCleanUp) override; /** * \brief initialize the execution */ - void initExecution(); + void initExecution() override; /** * \brief Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void checkOpenCL() { diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h index 8e7440b6fe4..a0abb0dd050 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h @@ -36,29 +36,29 @@ class GaussianYBlurOperation : public BlurBaseOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, std::list<cl_mem> *clMemToCleanUp, - std::list<cl_kernel> *clKernelsToCleanUp); + std::list<cl_kernel> *clKernelsToCleanUp) override; /** * \brief initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void checkOpenCL() { diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h index aabb76f5cf0..563877b734c 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.h +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h @@ -51,12 +51,12 @@ class GlareBaseOperation : public SingleThreadedOperation { /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setGlareSettings(NodeGlare *settings) { @@ -64,12 +64,12 @@ class GlareBaseOperation : public SingleThreadedOperation { } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; protected: GlareBaseOperation(); virtual void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) = 0; - MemoryBuffer *createMemoryBuffer(rcti *rect); + MemoryBuffer *createMemoryBuffer(rcti *rect) override; }; diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.h b/source/blender/compositor/operations/COM_GlareFogGlowOperation.h index 9084f27052e..844600527ee 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.h +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.h @@ -29,5 +29,5 @@ class GlareFogGlowOperation : public GlareBaseOperation { } protected: - void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); + void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) override; }; diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.h b/source/blender/compositor/operations/COM_GlareGhostOperation.h index 8ecf8da3385..1b6bf3b2603 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.h +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.h @@ -29,5 +29,5 @@ class GlareGhostOperation : public GlareBaseOperation { } protected: - void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); + void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) override; }; diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h index 0f5913fcef9..ab92e0019fa 100644 --- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h +++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h @@ -29,5 +29,5 @@ class GlareSimpleStarOperation : public GlareBaseOperation { } protected: - void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); + void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) override; }; diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.h b/source/blender/compositor/operations/COM_GlareStreaksOperation.h index df31981170d..833dbcfbb95 100644 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.h +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.h @@ -29,5 +29,5 @@ class GlareStreaksOperation : public GlareBaseOperation { } protected: - void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); + void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) override; }; diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.h b/source/blender/compositor/operations/COM_GlareThresholdOperation.h index 1e55f401ef3..34df10a0f81 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.h +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.h @@ -39,22 +39,23 @@ class GlareThresholdOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setGlareSettings(NodeGlare *settings) { this->m_settings = settings; } - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; }; diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h index dea7eae4a15..79eb40bbf60 100644 --- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h +++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h @@ -34,15 +34,15 @@ class HueSaturationValueCorrectOperation : public CurveBaseOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.h b/source/blender/compositor/operations/COM_IDMaskOperation.h index abd2a719371..9a8d553b184 100644 --- a/source/blender/compositor/operations/COM_IDMaskOperation.h +++ b/source/blender/compositor/operations/COM_IDMaskOperation.h @@ -27,8 +27,8 @@ class IDMaskOperation : public NodeOperation { public: IDMaskOperation(); - void *initializeTileData(rcti *rect); - void executePixel(float output[4], int x, int y, void *data); + void *initializeTileData(rcti *rect) override; + void executePixel(float output[4], int x, int y, void *data) override; void setObjectIndex(float objectIndex) { diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h index bff8dcc1cea..0bb92ce1b7e 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.h +++ b/source/blender/compositor/operations/COM_ImageOperation.h @@ -49,13 +49,14 @@ class BaseImageOperation : public NodeOperation { /** * Determine the output resolution. The resolution is retrieved from the Renderer */ - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; virtual ImBuf *getImBuf(); public: - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setImage(Image *image) { this->m_image = image; @@ -83,7 +84,7 @@ class ImageOperation : public BaseImageOperation { * Constructor */ ImageOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ImageAlphaOperation : public BaseImageOperation { public: @@ -91,7 +92,7 @@ class ImageAlphaOperation : public BaseImageOperation { * Constructor */ ImageAlphaOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ImageDepthOperation : public BaseImageOperation { public: @@ -99,5 +100,5 @@ class ImageDepthOperation : public BaseImageOperation { * Constructor */ ImageDepthOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_InpaintOperation.h b/source/blender/compositor/operations/COM_InpaintOperation.h index 4c43e433dec..8fefa475b4a 100644 --- a/source/blender/compositor/operations/COM_InpaintOperation.h +++ b/source/blender/compositor/operations/COM_InpaintOperation.h @@ -42,18 +42,18 @@ class InpaintSimpleOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setIterations(int iterations) { @@ -62,7 +62,7 @@ class InpaintSimpleOperation : public NodeOperation { bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; private: void calc_manhattan_distance(); diff --git a/source/blender/compositor/operations/COM_InvertOperation.h b/source/blender/compositor/operations/COM_InvertOperation.h index ac0b1c3ab2e..a7b0f823ae2 100644 --- a/source/blender/compositor/operations/COM_InvertOperation.h +++ b/source/blender/compositor/operations/COM_InvertOperation.h @@ -37,17 +37,17 @@ class InvertOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setColor(bool color) { diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.h b/source/blender/compositor/operations/COM_KeyingBlurOperation.h index 6a2b43a6cd4..b1ea4229b6d 100644 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.h +++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.h @@ -45,11 +45,11 @@ class KeyingBlurOperation : public NodeOperation { this->m_axis = value; } - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.h b/source/blender/compositor/operations/COM_KeyingClipOperation.h index 9d876966e96..1b2fa886814 100644 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.h +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.h @@ -59,11 +59,11 @@ class KeyingClipOperation : public NodeOperation { this->m_isEdgeMatte = value; } - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.h b/source/blender/compositor/operations/COM_KeyingDespillOperation.h index 32df7939c43..c201388c1c1 100644 --- a/source/blender/compositor/operations/COM_KeyingDespillOperation.h +++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.h @@ -33,8 +33,8 @@ class KeyingDespillOperation : public NodeOperation { public: KeyingDespillOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setDespillFactor(float value) { @@ -45,5 +45,5 @@ class KeyingDespillOperation : public NodeOperation { this->m_colorBalance = value; } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h index 946d7bdc1f7..13f4e5e247b 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.h +++ b/source/blender/compositor/operations/COM_KeyingOperation.h @@ -37,13 +37,13 @@ class KeyingOperation : public NodeOperation { public: KeyingOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setScreenBalance(float value) { this->m_screenBalance = value; } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h index 595301bb951..86cd94e308d 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.h +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h @@ -54,18 +54,19 @@ class KeyingScreenOperation : public NodeOperation { /** * Determine the output resolution. The resolution is retrieved from the Renderer */ - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; TriangulationData *buildVoronoiTriangulation(); public: KeyingScreenOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; - void *initializeTileData(rcti *rect); - void deinitializeTileData(rcti *rect, void *data); + void *initializeTileData(rcti *rect) override; + void deinitializeTileData(rcti *rect, void *data) override; void setMovieClip(MovieClip *clip) { @@ -80,5 +81,5 @@ class KeyingScreenOperation : public NodeOperation { this->m_framenumber = framenumber; } - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; }; diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h index 2c3a61d8755..4e716468568 100644 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h @@ -38,10 +38,10 @@ class LuminanceMatteOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setSettings(NodeChroma *nodeChroma) { diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.h b/source/blender/compositor/operations/COM_MapRangeOperation.h index 95268d5699f..27a7cfd90c3 100644 --- a/source/blender/compositor/operations/COM_MapRangeOperation.h +++ b/source/blender/compositor/operations/COM_MapRangeOperation.h @@ -47,17 +47,17 @@ class MapRangeOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; /** * Clamp the output diff --git a/source/blender/compositor/operations/COM_MapUVOperation.h b/source/blender/compositor/operations/COM_MapUVOperation.h index 66e70a7ab83..e3481b9cae9 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.h +++ b/source/blender/compositor/operations/COM_MapUVOperation.h @@ -38,24 +38,24 @@ class MapUVOperation : public NodeOperation { */ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; void pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2], float &r_alpha); /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setAlpha(float alpha) { diff --git a/source/blender/compositor/operations/COM_MapValueOperation.h b/source/blender/compositor/operations/COM_MapValueOperation.h index 3de377ed0fc..98417001f4a 100644 --- a/source/blender/compositor/operations/COM_MapValueOperation.h +++ b/source/blender/compositor/operations/COM_MapValueOperation.h @@ -42,17 +42,17 @@ class MapValueOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; /** * \brief set the TexMapping settings diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h index 67e6b64315c..909af921625 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.h +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -49,13 +49,14 @@ class MaskOperation : public NodeOperation { /** * Determine the output resolution. The resolution is retrieved from the Renderer */ - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; public: MaskOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setMask(Mask *mask) { @@ -91,5 +92,5 @@ class MaskOperation : public NodeOperation { this->m_frame_shutter = shutter; } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h index 292326caded..27a01667da5 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.h +++ b/source/blender/compositor/operations/COM_MathBaseOperation.h @@ -45,24 +45,20 @@ class MathBaseOperation : public NodeOperation { public: /** - * The inner loop of this operation. - */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) = 0; - - /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; /** * Determine resolution */ - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; void setUseClamp(bool value) { @@ -75,49 +71,49 @@ class MathAddOperation : public MathBaseOperation { MathAddOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathSubtractOperation : public MathBaseOperation { public: MathSubtractOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathMultiplyOperation : public MathBaseOperation { public: MathMultiplyOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathDivideOperation : public MathBaseOperation { public: MathDivideOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathSineOperation : public MathBaseOperation { public: MathSineOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathCosineOperation : public MathBaseOperation { public: MathCosineOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathTangentOperation : public MathBaseOperation { public: MathTangentOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathHyperbolicSineOperation : public MathBaseOperation { @@ -125,21 +121,21 @@ class MathHyperbolicSineOperation : public MathBaseOperation { MathHyperbolicSineOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathHyperbolicCosineOperation : public MathBaseOperation { public: MathHyperbolicCosineOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathHyperbolicTangentOperation : public MathBaseOperation { public: MathHyperbolicTangentOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathArcSineOperation : public MathBaseOperation { @@ -147,70 +143,70 @@ class MathArcSineOperation : public MathBaseOperation { MathArcSineOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathArcCosineOperation : public MathBaseOperation { public: MathArcCosineOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathArcTangentOperation : public MathBaseOperation { public: MathArcTangentOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathPowerOperation : public MathBaseOperation { public: MathPowerOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathLogarithmOperation : public MathBaseOperation { public: MathLogarithmOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathMinimumOperation : public MathBaseOperation { public: MathMinimumOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathMaximumOperation : public MathBaseOperation { public: MathMaximumOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathRoundOperation : public MathBaseOperation { public: MathRoundOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathLessThanOperation : public MathBaseOperation { public: MathLessThanOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathGreaterThanOperation : public MathBaseOperation { public: MathGreaterThanOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathModuloOperation : public MathBaseOperation { @@ -218,7 +214,7 @@ class MathModuloOperation : public MathBaseOperation { MathModuloOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathAbsoluteOperation : public MathBaseOperation { @@ -226,7 +222,7 @@ class MathAbsoluteOperation : public MathBaseOperation { MathAbsoluteOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathRadiansOperation : public MathBaseOperation { @@ -234,7 +230,7 @@ class MathRadiansOperation : public MathBaseOperation { MathRadiansOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathDegreesOperation : public MathBaseOperation { @@ -242,7 +238,7 @@ class MathDegreesOperation : public MathBaseOperation { MathDegreesOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathArcTan2Operation : public MathBaseOperation { @@ -250,7 +246,7 @@ class MathArcTan2Operation : public MathBaseOperation { MathArcTan2Operation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathFloorOperation : public MathBaseOperation { @@ -258,7 +254,7 @@ class MathFloorOperation : public MathBaseOperation { MathFloorOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathCeilOperation : public MathBaseOperation { @@ -266,7 +262,7 @@ class MathCeilOperation : public MathBaseOperation { MathCeilOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathFractOperation : public MathBaseOperation { @@ -274,7 +270,7 @@ class MathFractOperation : public MathBaseOperation { MathFractOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathSqrtOperation : public MathBaseOperation { @@ -282,7 +278,7 @@ class MathSqrtOperation : public MathBaseOperation { MathSqrtOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathInverseSqrtOperation : public MathBaseOperation { @@ -290,7 +286,7 @@ class MathInverseSqrtOperation : public MathBaseOperation { MathInverseSqrtOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathSignOperation : public MathBaseOperation { @@ -298,7 +294,7 @@ class MathSignOperation : public MathBaseOperation { MathSignOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathExponentOperation : public MathBaseOperation { @@ -306,7 +302,7 @@ class MathExponentOperation : public MathBaseOperation { MathExponentOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathTruncOperation : public MathBaseOperation { @@ -314,7 +310,7 @@ class MathTruncOperation : public MathBaseOperation { MathTruncOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathSnapOperation : public MathBaseOperation { @@ -322,7 +318,7 @@ class MathSnapOperation : public MathBaseOperation { MathSnapOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathWrapOperation : public MathBaseOperation { @@ -330,7 +326,7 @@ class MathWrapOperation : public MathBaseOperation { MathWrapOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathPingpongOperation : public MathBaseOperation { @@ -338,7 +334,7 @@ class MathPingpongOperation : public MathBaseOperation { MathPingpongOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathCompareOperation : public MathBaseOperation { @@ -346,7 +342,7 @@ class MathCompareOperation : public MathBaseOperation { MathCompareOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathMultiplyAddOperation : public MathBaseOperation { @@ -354,7 +350,7 @@ class MathMultiplyAddOperation : public MathBaseOperation { MathMultiplyAddOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathSmoothMinOperation : public MathBaseOperation { @@ -362,7 +358,7 @@ class MathSmoothMinOperation : public MathBaseOperation { MathSmoothMinOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MathSmoothMaxOperation : public MathBaseOperation { @@ -370,5 +366,5 @@ class MathSmoothMaxOperation : public MathBaseOperation { MathSmoothMaxOperation() : MathBaseOperation() { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_MixOperation.h b/source/blender/compositor/operations/COM_MixOperation.h index 2f6e03ca7a3..dd1f34a5322 100644 --- a/source/blender/compositor/operations/COM_MixOperation.h +++ b/source/blender/compositor/operations/COM_MixOperation.h @@ -52,19 +52,20 @@ class MixBaseOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; void setUseValueAlphaMultiply(const bool value) { @@ -83,113 +84,113 @@ class MixBaseOperation : public NodeOperation { class MixAddOperation : public MixBaseOperation { public: MixAddOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixBlendOperation : public MixBaseOperation { public: MixBlendOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixColorBurnOperation : public MixBaseOperation { public: MixColorBurnOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixColorOperation : public MixBaseOperation { public: MixColorOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixDarkenOperation : public MixBaseOperation { public: MixDarkenOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixDifferenceOperation : public MixBaseOperation { public: MixDifferenceOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixDivideOperation : public MixBaseOperation { public: MixDivideOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixDodgeOperation : public MixBaseOperation { public: MixDodgeOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixGlareOperation : public MixBaseOperation { public: MixGlareOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixHueOperation : public MixBaseOperation { public: MixHueOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixLightenOperation : public MixBaseOperation { public: MixLightenOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixLinearLightOperation : public MixBaseOperation { public: MixLinearLightOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixMultiplyOperation : public MixBaseOperation { public: MixMultiplyOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixOverlayOperation : public MixBaseOperation { public: MixOverlayOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixSaturationOperation : public MixBaseOperation { public: MixSaturationOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixScreenOperation : public MixBaseOperation { public: MixScreenOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixSoftLightOperation : public MixBaseOperation { public: MixSoftLightOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixSubtractOperation : public MixBaseOperation { public: MixSubtractOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MixValueOperation : public MixBaseOperation { public: MixValueOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h index 50ed6cdb69e..6a6920247e6 100644 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h @@ -45,13 +45,14 @@ class MovieClipAttributeOperation : public NodeOperation { */ MovieClipAttributeOperation(); - void initExecution(); + void initExecution() override; /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; void setMovieClip(MovieClip *clip) { diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h index 8897f85f77c..78cd1cc0c90 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipOperation.h @@ -39,13 +39,14 @@ class MovieClipBaseOperation : public NodeOperation { /** * Determine the output resolution. The resolution is retrieved from the Renderer */ - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; public: MovieClipBaseOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setMovieClip(MovieClip *image) { this->m_movieClip = image; @@ -63,7 +64,7 @@ class MovieClipBaseOperation : public NodeOperation { { this->m_framenumber = framenumber; } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class MovieClipOperation : public MovieClipBaseOperation { @@ -74,5 +75,5 @@ class MovieClipOperation : public MovieClipBaseOperation { class MovieClipAlphaOperation : public MovieClipBaseOperation { public: MovieClipAlphaOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index f11ce485f97..ef9d6be697b 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -40,10 +40,10 @@ class MovieDistortionOperation : public NodeOperation { public: MovieDistortionOperation(bool distortion); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setMovieClip(MovieClip *clip) { @@ -55,5 +55,5 @@ class MovieDistortionOperation : public NodeOperation { } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.h b/source/blender/compositor/operations/COM_NormalizeOperation.h index 8090cf4973b..6447aa930f1 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.h +++ b/source/blender/compositor/operations/COM_NormalizeOperation.h @@ -44,22 +44,22 @@ class NormalizeOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); - void deinitializeTileData(rcti *rect, void *data); + void *initializeTileData(rcti *rect) override; + void deinitializeTileData(rcti *rect, void *data) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h index 258ac1f9e98..90c683a57b5 100644 --- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h @@ -42,7 +42,7 @@ class OutputOpenExrSingleLayerMultiViewOperation : public OutputSingleLayerOpera const bool saveAsRender); void *get_handle(const char *filename); - void deinitExecution(); + void deinitExecution() override; }; /* Writes inputs into OpenEXR multilayer channels. */ @@ -58,7 +58,7 @@ class OutputOpenExrMultiLayerMultiViewOperation : public OutputOpenExrMultiLayer const char *viewName); void *get_handle(const char *filename); - void deinitExecution(); + void deinitExecution() override; }; class OutputStereoOperation : public OutputSingleLayerOperation { @@ -78,5 +78,5 @@ class OutputStereoOperation : public OutputSingleLayerOperation { const char *viewName, const bool saveAsRender); void *get_handle(const char *filename); - void deinitExecution(); + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h index ecc52355824..aa7ba35ddee 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileOperation.h @@ -57,19 +57,19 @@ class OutputSingleLayerOperation : public NodeOperation { const char *viewName, const bool saveAsRender); - void executeRegion(rcti *rect, unsigned int tileNumber); - bool isOutputOperation(bool /*rendering*/) const + void executeRegion(rcti *rect, unsigned int tileNumber) override; + bool isOutputOperation(bool /*rendering*/) const override { return true; } - void initExecution(); - void deinitExecution(); - CompositorPriority getRenderPriority() const + void initExecution() override; + void deinitExecution() override; + CompositorPriority getRenderPriority() const override { return CompositorPriority::Low; } - bool isFileOutputOperation() const + bool isFileOutputOperation() const override { return true; } @@ -116,19 +116,19 @@ class OutputOpenExrMultiLayerOperation : public NodeOperation { void add_layer(const char *name, DataType datatype, bool use_layer); - void executeRegion(rcti *rect, unsigned int tileNumber); - bool isOutputOperation(bool /*rendering*/) const + void executeRegion(rcti *rect, unsigned int tileNumber) override; + bool isOutputOperation(bool /*rendering*/) const override { return true; } - void initExecution(); - void deinitExecution(); - CompositorPriority getRenderPriority() const + void initExecution() override; + void deinitExecution() override; + CompositorPriority getRenderPriority() const override { return CompositorPriority::Low; } - bool isFileOutputOperation() const + bool isFileOutputOperation() const override { return true; } diff --git a/source/blender/compositor/operations/COM_PixelateOperation.h b/source/blender/compositor/operations/COM_PixelateOperation.h index c7595756d39..aae54965aa4 100644 --- a/source/blender/compositor/operations/COM_PixelateOperation.h +++ b/source/blender/compositor/operations/COM_PixelateOperation.h @@ -44,12 +44,12 @@ class PixelateOperation : public NodeOperation { /** * \brief initialization of the execution */ - void initExecution(); + void initExecution() override; /** * \brief de-initialization of the execution */ - void deinitExecution(); + void deinitExecution() override; /** * \brief executePixel @@ -58,5 +58,5 @@ class PixelateOperation : public NodeOperation { * \param y: y-coordinate * \param sampler: sampler */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h index 1e892465db8..6edecff0d54 100644 --- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h +++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h @@ -34,12 +34,13 @@ class PlaneCornerPinMaskOperation : public PlaneDistortMaskOperation { public: PlaneCornerPinMaskOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; }; class PlaneCornerPinWarpImageOperation : public PlaneDistortWarpImageOperation { @@ -49,12 +50,12 @@ class PlaneCornerPinWarpImageOperation : public PlaneDistortWarpImageOperation { public: PlaneCornerPinWarpImageOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h index 6cc9456c13f..c17f99a6710 100644 --- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h +++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h @@ -46,14 +46,14 @@ class PlaneDistortWarpImageOperation : public NodeOperation { void calculateCorners(const float corners[4][2], bool normalized, int sample); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void setMotionBlurSamples(int samples) { @@ -82,9 +82,9 @@ class PlaneDistortMaskOperation : public NodeOperation { void calculateCorners(const float corners[4][2], bool normalized, int sample); - void initExecution(); + void initExecution() override; - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; void setMotionBlurSamples(int samples) { diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h index fc325c7db7d..6cfb3accaa3 100644 --- a/source/blender/compositor/operations/COM_PlaneTrackOperation.h +++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.h @@ -68,9 +68,10 @@ class PlaneTrackMaskOperation : public PlaneDistortMaskOperation, public PlaneTr { } - void initExecution(); + void initExecution() override; - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override { PlaneTrackCommon::determineResolution(resolution, preferredResolution); @@ -86,9 +87,10 @@ class PlaneTrackWarpImageOperation : public PlaneDistortWarpImageOperation, { } - void initExecution(); + void initExecution() override; - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override { PlaneTrackCommon::determineResolution(resolution, preferredResolution); unsigned int temp[2]; diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h index 03ae6a6c42e..36ae5f59bb9 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.h +++ b/source/blender/compositor/operations/COM_PreviewOperation.h @@ -47,20 +47,21 @@ class PreviewOperation : public NodeOperation { unsigned int defaultHeight); void verifyPreview(bNodeInstanceHash *previews, bNodeInstanceKey key); - bool isOutputOperation(bool /*rendering*/) const + bool isOutputOperation(bool /*rendering*/) const override { return !G.background; } - void initExecution(); - void deinitExecution(); - CompositorPriority getRenderPriority() const; + void initExecution() override; + void deinitExecution() override; + CompositorPriority getRenderPriority() const override; - void executeRegion(rcti *rect, unsigned int tileNumber); - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void executeRegion(rcti *rect, unsigned int tileNumber) override; + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - bool isPreviewOperation() const + rcti *output) override; + bool isPreviewOperation() const override { return true; } diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h index 96bede20623..b47d4f37589 100644 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h @@ -39,22 +39,22 @@ class ProjectorLensDistortionOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void updateDispersion(); }; diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h index 2ada33906ef..21ef716b727 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.h +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h @@ -39,18 +39,19 @@ class ReadBufferOperation : public NodeOperation { { return this->m_memoryProxy; } - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; - void *initializeTileData(rcti *rect); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void *initializeTileData(rcti *rect) override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; void executePixelExtend(float output[4], float x, float y, PixelSampler sampler, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y); - void executePixelFiltered(float output[4], float x, float y, float dx[2], float dy[2]); - bool isReadBufferOperation() const + void executePixelFiltered(float output[4], float x, float y, float dx[2], float dy[2]) override; + bool isReadBufferOperation() const override { return true; } @@ -64,8 +65,8 @@ class ReadBufferOperation : public NodeOperation { } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - MemoryBuffer *getInputMemoryBuffer(MemoryBuffer **memoryBuffers) + rcti *output) override; + MemoryBuffer *getInputMemoryBuffer(MemoryBuffer **memoryBuffers) override { return memoryBuffers[this->m_offset]; } diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h index a0d5bc2953b..f3e1c892a83 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersProg.h @@ -132,7 +132,7 @@ class RenderLayersAOOperation : public RenderLayersProg { : RenderLayersProg(passName, type, elementsize) { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class RenderLayersAlphaProg : public RenderLayersProg { @@ -141,7 +141,7 @@ class RenderLayersAlphaProg : public RenderLayersProg { : RenderLayersProg(passName, type, elementsize) { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class RenderLayersDepthProg : public RenderLayersProg { @@ -150,5 +150,5 @@ class RenderLayersDepthProg : public RenderLayersProg { : RenderLayersProg(passName, type, elementsize) { } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_RotateOperation.h b/source/blender/compositor/operations/COM_RotateOperation.h index 0ef4466671a..9b9d5987a8e 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.h +++ b/source/blender/compositor/operations/COM_RotateOperation.h @@ -35,10 +35,10 @@ class RotateOperation : public NodeOperation { RotateOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); - void initExecution(); - void deinitExecution(); + rcti *output) override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; + void initExecution() override; + void deinitExecution() override; void setDoDegree2RadConversion(bool abool) { this->m_doDegree2RadConversion = abool; diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index f28b8237485..780107910f9 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -55,11 +55,11 @@ class ScaleOperation : public BaseScaleOperation { ScaleOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + rcti *output) override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; }; class ScaleAbsoluteOperation : public BaseScaleOperation { @@ -73,11 +73,11 @@ class ScaleAbsoluteOperation : public BaseScaleOperation { ScaleAbsoluteOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + rcti *output) override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; }; class ScaleFixedSizeOperation : public BaseScaleOperation { @@ -100,12 +100,13 @@ class ScaleFixedSizeOperation : public BaseScaleOperation { ScaleFixedSizeOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + rcti *output) override; + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setNewWidth(int width) { this->m_newWidth = width; diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h index 35d2bccce68..793fc95dc3d 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h @@ -49,18 +49,18 @@ class ScreenLensDistortionOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setFit(bool fit) { @@ -78,7 +78,7 @@ class ScreenLensDistortionOperation : public NodeOperation { bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; private: void determineUV(float result[6], float x, float y) const; diff --git a/source/blender/compositor/operations/COM_SetAlphaMultiplyOperation.h b/source/blender/compositor/operations/COM_SetAlphaMultiplyOperation.h index db58b18688a..094da1fd493 100644 --- a/source/blender/compositor/operations/COM_SetAlphaMultiplyOperation.h +++ b/source/blender/compositor/operations/COM_SetAlphaMultiplyOperation.h @@ -33,8 +33,8 @@ class SetAlphaMultiplyOperation : public NodeOperation { public: SetAlphaMultiplyOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_SetAlphaReplaceOperation.h b/source/blender/compositor/operations/COM_SetAlphaReplaceOperation.h index b4cab82855b..313d5f581eb 100644 --- a/source/blender/compositor/operations/COM_SetAlphaReplaceOperation.h +++ b/source/blender/compositor/operations/COM_SetAlphaReplaceOperation.h @@ -38,8 +38,8 @@ class SetAlphaReplaceOperation : public NodeOperation { /** * the inner loop of this program */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_SetColorOperation.h b/source/blender/compositor/operations/COM_SetColorOperation.h index c61a4e10ac0..147e76c433f 100644 --- a/source/blender/compositor/operations/COM_SetColorOperation.h +++ b/source/blender/compositor/operations/COM_SetColorOperation.h @@ -74,10 +74,11 @@ class SetColorOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); - bool isSetOperation() const + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; + bool isSetOperation() const override { return true; } diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.h b/source/blender/compositor/operations/COM_SetSamplerOperation.h index 5c1ed9b12d6..4a0bd4563bb 100644 --- a/source/blender/compositor/operations/COM_SetSamplerOperation.h +++ b/source/blender/compositor/operations/COM_SetSamplerOperation.h @@ -43,7 +43,7 @@ class SetSamplerOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); - void initExecution(); - void deinitExecution(); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; + void initExecution() override; + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_SetValueOperation.h b/source/blender/compositor/operations/COM_SetValueOperation.h index 72cd70ec1f6..b3edb215010 100644 --- a/source/blender/compositor/operations/COM_SetValueOperation.h +++ b/source/blender/compositor/operations/COM_SetValueOperation.h @@ -46,10 +46,11 @@ class SetValueOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; - bool isSetOperation() const + bool isSetOperation() const override { return true; } diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.h b/source/blender/compositor/operations/COM_SetVectorOperation.h index 4bdd03809de..a48584d7ded 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.h +++ b/source/blender/compositor/operations/COM_SetVectorOperation.h @@ -73,10 +73,11 @@ class SetVectorOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); - bool isSetOperation() const + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; + bool isSetOperation() const override { return true; } diff --git a/source/blender/compositor/operations/COM_SplitOperation.h b/source/blender/compositor/operations/COM_SplitOperation.h index 62d41a615ff..ace5fd62eb2 100644 --- a/source/blender/compositor/operations/COM_SplitOperation.h +++ b/source/blender/compositor/operations/COM_SplitOperation.h @@ -30,10 +30,11 @@ class SplitOperation : public NodeOperation { public: SplitOperation(); - void initExecution(); - void deinitExecution(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void initExecution() override; + void deinitExecution() override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; void setSplitPercentage(float splitPercentage) { this->m_splitPercentage = splitPercentage; diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.h b/source/blender/compositor/operations/COM_SunBeamsOperation.h index 09bdb018cc3..7cf5cf9971e 100644 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.h +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.h @@ -23,15 +23,15 @@ class SunBeamsOperation : public NodeOperation { public: SunBeamsOperation(); - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void setData(const NodeSunBeams &data) { diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h index a40dafd14cf..1a6e005f752 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.h +++ b/source/blender/compositor/operations/COM_TextureOperation.h @@ -44,7 +44,8 @@ class TextureBaseOperation : public NodeOperation { /** * Determine the output resolution. The resolution is retrieved from the Renderer */ - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; /** * Constructor @@ -52,14 +53,14 @@ class TextureBaseOperation : public NodeOperation { TextureBaseOperation(); public: - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; void setTexture(Tex *texture) { this->m_texture = texture; } - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; void setRenderData(const RenderData *rd) { this->m_rd = rd; @@ -77,5 +78,5 @@ class TextureOperation : public TextureBaseOperation { class TextureAlphaOperation : public TextureBaseOperation { public: TextureAlphaOperation(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h index cb8816b93b3..e7da983fe61 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.h +++ b/source/blender/compositor/operations/COM_TonemapOperation.h @@ -60,20 +60,20 @@ class TonemapOperation : public NodeOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); - void deinitializeTileData(rcti *rect, void *data); + void *initializeTileData(rcti *rect) override; + void deinitializeTileData(rcti *rect, void *data) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; void setData(NodeTonemap *data) { @@ -82,7 +82,7 @@ class TonemapOperation : public NodeOperation { bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; }; /** @@ -96,5 +96,5 @@ class PhotoreceptorTonemapOperation : public TonemapOperation { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; }; diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h index 7d831ec5d8d..2e2c1f36c52 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.h +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.h @@ -49,7 +49,8 @@ class TrackPositionOperation : public NodeOperation { /** * Determine the output resolution. The resolution is retrieved from the Renderer */ - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; public: TrackPositionOperation(); @@ -87,11 +88,11 @@ class TrackPositionOperation : public NodeOperation { this->m_speed_output = speed_output; } - void initExecution(); + void initExecution() override; - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - bool isSetOperation() const + bool isSetOperation() const override { return true; } diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h index 99cfb528858..d55cc9096c0 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.h +++ b/source/blender/compositor/operations/COM_TranslateOperation.h @@ -35,11 +35,11 @@ class TranslateOperation : public NodeOperation { TranslateOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + rcti *output) override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; float getDeltaX() { diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h index fe927f791fa..5b859e5a2fd 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h @@ -41,25 +41,25 @@ class VariableSizeBokehBlurOperation : public NodeOperation, public QualityStepH /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; - void deinitializeTileData(rcti *rect, void *data); + void deinitializeTileData(rcti *rect, void *data) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; void setMaxBlur(int maxRadius) { @@ -81,7 +81,7 @@ class VariableSizeBokehBlurOperation : public NodeOperation, public QualityStepH cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, std::list<cl_mem> *clMemToCleanUp, - std::list<cl_kernel> *clKernelsToCleanUp); + std::list<cl_kernel> *clKernelsToCleanUp) override; }; #ifdef COM_DEFOCUS_SEARCH @@ -103,19 +103,20 @@ class InverseSearchRadiusOperation : public NodeOperation { /** * Initialize the execution */ - void initExecution(); - void *initializeTileData(rcti *rect); - void deinitializeTileData(rcti *rect, void *data); + void initExecution() override; + void *initializeTileData(rcti *rect) override; + void deinitializeTileData(rcti *rect, void *data) override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + rcti *output) override; + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; void setMaxBlur(int maxRadius) { diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.h b/source/blender/compositor/operations/COM_VectorBlurOperation.h index 222e8b26968..10affb48f20 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.h +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.h @@ -44,19 +44,19 @@ class VectorBlurOperation : public NodeOperation, public QualityStepHelper { /** * The inner loop of this operation. */ - void executePixel(float output[4], int x, int y, void *data); + void executePixel(float output[4], int x, int y, void *data) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; - void *initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect) override; void setVectorBlurSettings(NodeBlurData *settings) { @@ -64,7 +64,7 @@ class VectorBlurOperation : public NodeOperation, public QualityStepHelper { } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); + rcti *output) override; protected: void generateVectorBlur(float *data, diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.h b/source/blender/compositor/operations/COM_VectorCurveOperation.h index cf0d22eca1a..0c164a1f3c8 100644 --- a/source/blender/compositor/operations/COM_VectorCurveOperation.h +++ b/source/blender/compositor/operations/COM_VectorCurveOperation.h @@ -34,15 +34,15 @@ class VectorCurveOperation : public CurveBaseOperation { /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; /** * Initialize the execution */ - void initExecution(); + void initExecution() override; /** * Deinitialize the execution */ - void deinitExecution(); + void deinitExecution() override; }; diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h index 513c6eae487..a3df19d5e90 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.h +++ b/source/blender/compositor/operations/COM_ViewerOperation.h @@ -48,11 +48,12 @@ class ViewerOperation : public NodeOperation { public: ViewerOperation(); - void initExecution(); - void deinitExecution(); - void executeRegion(rcti *rect, unsigned int tileNumber); - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); - bool isOutputOperation(bool /*rendering*/) const + void initExecution() override; + void deinitExecution() override; + void executeRegion(rcti *rect, unsigned int tileNumber) override; + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; + bool isOutputOperation(bool /*rendering*/) const override { if (G.background) { return false; @@ -67,7 +68,7 @@ class ViewerOperation : public NodeOperation { { this->m_imageUser = imageUser; } - bool isActiveViewerOutput() const + bool isActiveViewerOutput() const override { return this->m_active; } @@ -99,8 +100,8 @@ class ViewerOperation : public NodeOperation { { return this->m_chunkOrder; } - CompositorPriority getRenderPriority() const; - bool isViewerOperation() const + CompositorPriority getRenderPriority() const override; + bool isViewerOperation() const override { return true; } diff --git a/source/blender/compositor/operations/COM_WrapOperation.h b/source/blender/compositor/operations/COM_WrapOperation.h index a72b90e7e94..21123ed490c 100644 --- a/source/blender/compositor/operations/COM_WrapOperation.h +++ b/source/blender/compositor/operations/COM_WrapOperation.h @@ -28,8 +28,8 @@ class WrapOperation : public ReadBufferOperation { WrapOperation(DataType datatype); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, - rcti *output); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + rcti *output) override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; void setWrapping(int wrapping_type); float getWrappedOriginalXPos(float x); diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h index a9f90830a92..00d48e38fca 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.h +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -37,8 +37,8 @@ class WriteBufferOperation : public NodeOperation { { return this->m_memoryProxy; } - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); - bool isWriteBufferOperation() const + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; + bool isWriteBufferOperation() const override { return true; } @@ -47,15 +47,16 @@ class WriteBufferOperation : public NodeOperation { return m_single_value; } - void executeRegion(rcti *rect, unsigned int tileNumber); - void initExecution(); - void deinitExecution(); + void executeRegion(rcti *rect, unsigned int tileNumber) override; + void initExecution() override; + void deinitExecution() override; void executeOpenCLRegion(OpenCLDevice *device, rcti *rect, unsigned int chunkNumber, MemoryBuffer **memoryBuffers, - MemoryBuffer *outputBuffer); - void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); + MemoryBuffer *outputBuffer) override; + void determineResolution(unsigned int resolution[2], + unsigned int preferredResolution[2]) override; void readResolutionFromInputSocket(); inline NodeOperation *getInput() { diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.h b/source/blender/compositor/operations/COM_ZCombineOperation.h index a64e3c5b70f..91044d44985 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.h +++ b/source/blender/compositor/operations/COM_ZCombineOperation.h @@ -37,17 +37,17 @@ class ZCombineOperation : public NodeOperation { */ ZCombineOperation(); - void initExecution(); - void deinitExecution(); + void initExecution() override; + void deinitExecution() override; /** * The inner loop of this operation. */ - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ZCombineAlphaOperation : public ZCombineOperation { - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ZCombineMaskOperation : public NodeOperation { @@ -59,10 +59,10 @@ class ZCombineMaskOperation : public NodeOperation { public: ZCombineMaskOperation(); - void initExecution(); - void deinitExecution(); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void initExecution() override; + void deinitExecution() override; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; class ZCombineMaskAlphaOperation : public ZCombineMaskOperation { - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; }; diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c index d362ec23370..e3fc8b73172 100644 --- a/source/blender/editors/curve/editcurve_select.c +++ b/source/blender/editors/curve/editcurve_select.c @@ -578,8 +578,8 @@ static int de_select_all_exec(bContext *C, wmOperator *op) changed = ED_curve_deselect_all(cu->editnurb); break; case SEL_INVERT: - changed = ED_curve_select_swap(cu->editnurb, - v3d->overlay.handle_display == CURVE_HANDLE_NONE); + changed = ED_curve_select_swap( + cu->editnurb, (v3d && (v3d->overlay.handle_display == CURVE_HANDLE_NONE))); break; } diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 5c041134a74..574670de7ca 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -596,6 +596,21 @@ bool ED_gpencil_stroke_material_editable(Object *ob, const bGPDlayer *gpl, const return true; } +/* Check whether given stroke is visible for the current material. */ +bool ED_gpencil_stroke_material_visible(Object *ob, const bGPDstroke *gps) +{ + /* check if the color is editable */ + MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1); + + if (gp_style != NULL) { + if (gp_style->flag & GP_MATERIAL_HIDE) { + return false; + } + } + + return true; +} + /* ******************************************************** */ /* Space Conversion */ diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index f3b5abb1072..e9ac21f60cf 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -150,6 +150,7 @@ bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke bool ED_gpencil_stroke_material_editable(struct Object *ob, const struct bGPDlayer *gpl, const struct bGPDstroke *gps); +bool ED_gpencil_stroke_material_visible(struct Object *ob, const struct bGPDstroke *gps); /* ----------- Grease Pencil Operators ----------------- */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index fbd7dcd61f2..279239fcc65 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1816,6 +1816,29 @@ static void ui_but_validate(const uiBut *but) } #endif +/** + * Check if the operator \a ot poll is successfull with the context given by \a but (optionally). + * \param but: The button that might store context. Can be NULL for convenience (e.g. if there is + * no button to take context from, but we still want to poll the operator). + */ +bool ui_but_context_poll_operator(bContext *C, wmOperatorType *ot, const uiBut *but) +{ + bool result; + int opcontext = but ? but->opcontext : WM_OP_INVOKE_DEFAULT; + + if (but && but->context) { + CTX_store_set(C, but->context); + } + + result = WM_operator_poll_context(C, ot, opcontext); + + if (but && but->context) { + CTX_store_set(C, NULL); + } + + return result; +} + void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2]) { wmWindow *window = CTX_wm_window(C); @@ -1841,17 +1864,9 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x if (but->optype) { wmOperatorType *ot = but->optype; - if (but->context) { - CTX_store_set((bContext *)C, but->context); - } - - if (ot == NULL || WM_operator_poll_context((bContext *)C, ot, but->opcontext) == 0) { + if (ot == NULL || !ui_but_context_poll_operator((bContext *)C, ot, but)) { but->flag |= UI_BUT_DISABLED; } - - if (but->context) { - CTX_store_set((bContext *)C, NULL); - } } const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index fb8d32b3b84..178f663ff58 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -153,7 +153,7 @@ uiBut *eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *ev { bScreen *screen = CTX_wm_screen(C); ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y); - ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_ANY, event->x, event->y); + const ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_ANY, event->x, event->y); uiBut *but = ui_but_find_mouse_over(region, event); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index ee5c3f53f5e..a5a5a69728e 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1594,7 +1594,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void if (done) { wmWindow *win = CTX_wm_window(C); - ARegion *region = CTX_wm_region(C); + const ARegion *region = CTX_wm_region(C); uiBut *but = ui_but_find_mouse_over_ex( region, drag_info->xy_init[0], drag_info->xy_init[1], true); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 1d4a44e0c76..4c96512b4f3 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -647,6 +647,8 @@ extern bool ui_but_menu_draw_as_popover(const uiBut *but); void ui_but_range_set_hard(uiBut *but); void ui_but_range_set_soft(uiBut *but); +bool ui_but_context_poll_operator(struct bContext *C, struct wmOperatorType *ot, const uiBut *but); + extern void ui_but_update(uiBut *but); extern void ui_but_update_edited(uiBut *but); extern bool ui_but_is_float(const uiBut *but) ATTR_WARN_UNUSED_RESULT; @@ -1108,11 +1110,11 @@ bool ui_but_contains_point_px(const uiBut *but, const struct ARegion *region, in uiBut *ui_list_find_mouse_over(struct ARegion *region, const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT; -uiBut *ui_but_find_mouse_over_ex(struct ARegion *region, +uiBut *ui_but_find_mouse_over_ex(const struct ARegion *region, const int x, const int y, const bool labeledit) ATTR_WARN_UNUSED_RESULT; -uiBut *ui_but_find_mouse_over(struct ARegion *region, +uiBut *ui_but_find_mouse_over(const struct ARegion *region, const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT; uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c index 83e48fad157..aa10d092f5e 100644 --- a/source/blender/editors/interface/interface_query.c +++ b/source/blender/editors/interface/interface_query.c @@ -265,7 +265,10 @@ bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *region, const wmEv } /* x and y are only used in case event is NULL... */ -uiBut *ui_but_find_mouse_over_ex(ARegion *region, const int x, const int y, const bool labeledit) +uiBut *ui_but_find_mouse_over_ex(const ARegion *region, + const int x, + const int y, + const bool labeledit) { uiBut *butover = NULL; @@ -303,7 +306,7 @@ uiBut *ui_but_find_mouse_over_ex(ARegion *region, const int x, const int y, cons return butover; } -uiBut *ui_but_find_mouse_over(ARegion *region, const wmEvent *event) +uiBut *ui_but_find_mouse_over(const ARegion *region, const wmEvent *event) { return ui_but_find_mouse_over_ex(region, event->x, event->y, event->ctrl != 0); } diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index eaefc2c3736..ad0c523a594 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -23,6 +23,7 @@ #include <limits.h> #include <math.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c index 74668b2f3a3..ff42d434f29 100644 --- a/source/blender/editors/interface/interface_template_search_menu.c +++ b/source/blender/editors/interface/interface_template_search_menu.c @@ -21,6 +21,7 @@ * Accessed via the #WM_OT_search_menu operator. */ +#include <stdio.h> #include <string.h> #include "MEM_guardedalloc.h" diff --git a/source/blender/editors/io/CMakeLists.txt b/source/blender/editors/io/CMakeLists.txt index e7effd05d34..d45c7ca9b75 100644 --- a/source/blender/editors/io/CMakeLists.txt +++ b/source/blender/editors/io/CMakeLists.txt @@ -24,6 +24,7 @@ set(INC ../../depsgraph ../../io/alembic ../../io/collada + ../../io/gpencil ../../io/usd ../../makesdna ../../makesrna @@ -39,12 +40,16 @@ set(SRC io_alembic.c io_cache.c io_collada.c + io_gpencil_import.c + io_gpencil_export.c + io_gpencil_utils.c io_ops.c io_usd.c io_alembic.h io_cache.h io_collada.h + io_gpencil.h io_ops.h io_usd.h ) @@ -79,4 +84,14 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() +if(WITH_PUGIXML) + add_definitions(-DWITH_PUGIXML) +endif() + +if(WITH_HARU) + add_definitions(-DWITH_HARU) +endif() + +list(APPEND LIB bf_gpencil) + blender_add_lib(bf_editor_io "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/io/io_gpencil.h b/source/blender/editors/io/io_gpencil.h new file mode 100644 index 00000000000..98cb8b13310 --- /dev/null +++ b/source/blender/editors/io/io_gpencil.h @@ -0,0 +1,45 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation. + * All rights reserved. + */ + +#ifndef __IO_GPENCIL_H__ +#define __IO_GPENCIL_H__ + +/** \file + * \ingroup editor/io + */ + +struct ARegion; +struct bContext; +struct View3D; +struct wmOperator; +struct wmOperatorType; + +void WM_OT_gpencil_import_svg(struct wmOperatorType *ot); + +#ifdef WITH_PUGIXML +void WM_OT_gpencil_export_svg(struct wmOperatorType *ot); +#endif +#ifdef WITH_HARU +void WM_OT_gpencil_export_pdf(struct wmOperatorType *ot); +#endif + +struct ARegion *get_invoke_region(struct bContext *C); +struct View3D *get_invoke_view3d(struct bContext *C); + +#endif /* __IO_GPENCIL_H__ */ diff --git a/source/blender/editors/io/io_gpencil_export.c b/source/blender/editors/io/io_gpencil_export.c new file mode 100644 index 00000000000..98e30f51116 --- /dev/null +++ b/source/blender/editors/io/io_gpencil_export.c @@ -0,0 +1,430 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup editor/io + */ + +#include "BLI_path_util.h" +#include "BLI_string.h" + +#include "DNA_gpencil_types.h" +#include "DNA_space_types.h" + +#include "BKE_gpencil.h" +#include "BKE_main.h" +#include "BKE_report.h" +#include "BKE_screen.h" + +#include "BLT_translation.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "io_gpencil.h" + +#include "gpencil_io.h" + +/* Definition of enum elements to export. */ +/* Common props for exporting. */ +static void gpencil_export_common_props_definition(wmOperatorType *ot) +{ + static const EnumPropertyItem select_items[] = { + {GP_EXPORT_ACTIVE, "ACTIVE", 0, "Active", "Include only the active object"}, + {GP_EXPORT_SELECTED, "SELECTED", 0, "Selected", "Include selected objects"}, + {GP_EXPORT_VISIBLE, "VISIBLE", 0, "Visible", "Include all visible objects"}, + {0, NULL, 0, NULL, NULL}, + }; + + RNA_def_boolean(ot->srna, "use_fill", true, "Fill", "Export strokes with fill enabled"); + RNA_def_enum(ot->srna, + "selected_object_type", + select_items, + GP_EXPORT_SELECTED, + "Object", + "Which objects to include in the export"); + RNA_def_float(ot->srna, + "stroke_sample", + 0.0f, + 0.0f, + 100.0f, + "Sampling", + "Precision of stroke sampling. Low values mean a more precise result, and zero " + "disables sampling", + 0.0f, + 100.0f); + RNA_def_boolean(ot->srna, + "use_normalized_thickness", + false, + "Normalize", + "Export strokes with constant thickness"); +} + +static void set_export_filepath(bContext *C, wmOperator *op, const char *extension) +{ + if (!RNA_struct_property_is_set(op->ptr, "filepath")) { + Main *bmain = CTX_data_main(C); + char filepath[FILE_MAX]; + + if (BKE_main_blendfile_path(bmain)[0] == '\0') { + BLI_strncpy(filepath, "untitled", sizeof(filepath)); + } + else { + BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath)); + } + + BLI_path_extension_replace(filepath, sizeof(filepath), extension); + RNA_string_set(op->ptr, "filepath", filepath); + } +} + +/* <-------- SVG single frame export. --------> */ +#ifdef WITH_PUGIXML +static bool wm_gpencil_export_svg_common_check(bContext *UNUSED(C), wmOperator *op) +{ + char filepath[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", filepath); + + if (!BLI_path_extension_check(filepath, ".svg")) { + BLI_path_extension_ensure(filepath, FILE_MAX, ".svg"); + RNA_string_set(op->ptr, "filepath", filepath); + return true; + } + + return false; +} + +static int wm_gpencil_export_svg_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + set_export_filepath(C, op, ".svg"); + + WM_event_add_fileselect(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int wm_gpencil_export_svg_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); + + if (!RNA_struct_property_is_set(op->ptr, "filepath")) { + BKE_report(op->reports, RPT_ERROR, "No filename given"); + return OPERATOR_CANCELLED; + } + + ARegion *region = get_invoke_region(C); + if (region == NULL) { + BKE_report(op->reports, RPT_ERROR, "Unable to find valid 3D View area"); + return OPERATOR_CANCELLED; + } + View3D *v3d = get_invoke_view3d(C); + + char filename[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", filename); + + const bool use_fill = RNA_boolean_get(op->ptr, "use_fill"); + const bool use_norm_thickness = RNA_boolean_get(op->ptr, "use_normalized_thickness"); + const eGpencilExportSelect select_mode = RNA_enum_get(op->ptr, "selected_object_type"); + + const bool use_clip_camera = RNA_boolean_get(op->ptr, "use_clip_camera"); + + /* Set flags. */ + int flag = 0; + SET_FLAG_FROM_TEST(flag, use_fill, GP_EXPORT_FILL); + SET_FLAG_FROM_TEST(flag, use_norm_thickness, GP_EXPORT_NORM_THICKNESS); + SET_FLAG_FROM_TEST(flag, use_clip_camera, GP_EXPORT_CLIP_CAMERA); + + GpencilIOParams params = {.C = C, + .region = region, + .v3d = v3d, + .ob = ob, + .mode = GP_EXPORT_TO_SVG, + .frame_start = CFRA, + .frame_end = CFRA, + .frame_cur = CFRA, + .flag = flag, + .scale = 1.0f, + .select_mode = select_mode, + .frame_mode = GP_EXPORT_FRAME_ACTIVE, + .stroke_sample = RNA_float_get(op->ptr, "stroke_sample"), + .resolution = 1.0f}; + + /* Do export. */ + WM_cursor_wait(true); + const bool done = gpencil_io_export(filename, ¶ms); + WM_cursor_wait(false); + + if (!done) { + BKE_report(op->reports, RPT_WARNING, "Unable to export SVG"); + } + + return OPERATOR_FINISHED; +} + +static void ui_gpencil_export_svg_settings(uiLayout *layout, PointerRNA *imfptr) +{ + uiLayout *box, *row; + + uiLayoutSetPropSep(layout, true); + uiLayoutSetPropDecorate(layout, false); + + box = uiLayoutBox(layout); + + row = uiLayoutRow(box, false); + uiItemL(row, IFACE_("Scene Options"), ICON_NONE); + + row = uiLayoutRow(box, false); + uiItemR(row, imfptr, "selected_object_type", 0, NULL, ICON_NONE); + + box = uiLayoutBox(layout); + row = uiLayoutRow(box, false); + uiItemL(row, IFACE_("Export Options"), ICON_NONE); + + uiLayout *col = uiLayoutColumn(box, false); + uiItemR(col, imfptr, "stroke_sample", 0, NULL, ICON_NONE); + uiItemR(col, imfptr, "use_fill", 0, NULL, ICON_NONE); + uiItemR(col, imfptr, "use_normalized_thickness", 0, NULL, ICON_NONE); + uiItemR(col, imfptr, "use_clip_camera", 0, NULL, ICON_NONE); +} + +static void wm_gpencil_export_svg_draw(bContext *UNUSED(C), wmOperator *op) +{ + PointerRNA ptr; + + RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); + + ui_gpencil_export_svg_settings(op->layout, &ptr); +} + +static bool wm_gpencil_export_svg_poll(bContext *C) +{ + if ((CTX_wm_window(C) == NULL) || (CTX_data_mode_enum(C) != CTX_MODE_OBJECT)) { + return false; + } + + return true; +} + +void WM_OT_gpencil_export_svg(wmOperatorType *ot) +{ + ot->name = "Export to SVG"; + ot->description = "Export grease pencil to SVG"; + ot->idname = "WM_OT_gpencil_export_svg"; + + ot->invoke = wm_gpencil_export_svg_invoke; + ot->exec = wm_gpencil_export_svg_exec; + ot->poll = wm_gpencil_export_svg_poll; + ot->ui = wm_gpencil_export_svg_draw; + ot->check = wm_gpencil_export_svg_common_check; + + WM_operator_properties_filesel(ot, + FILE_TYPE_OBJECT_IO, + FILE_BLENDER, + FILE_SAVE, + WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS, + FILE_DEFAULTDISPLAY, + FILE_SORT_ALPHA); + + gpencil_export_common_props_definition(ot); + + RNA_def_boolean(ot->srna, + "use_clip_camera", + false, + "Clip Camera", + "Clip drawings to camera size when export in camera view"); +} +#endif + +/* <-------- PDF single frame export. --------> */ +#ifdef WITH_HARU +static bool wm_gpencil_export_pdf_common_check(bContext *UNUSED(C), wmOperator *op) +{ + + char filepath[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", filepath); + + if (!BLI_path_extension_check(filepath, ".pdf")) { + BLI_path_extension_ensure(filepath, FILE_MAX, ".pdf"); + RNA_string_set(op->ptr, "filepath", filepath); + return true; + } + + return false; +} + +static int wm_gpencil_export_pdf_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + set_export_filepath(C, op, ".pdf"); + + WM_event_add_fileselect(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int wm_gpencil_export_pdf_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); + + if (!RNA_struct_property_is_set(op->ptr, "filepath")) { + BKE_report(op->reports, RPT_ERROR, "No filename given"); + return OPERATOR_CANCELLED; + } + + ARegion *region = get_invoke_region(C); + if (region == NULL) { + BKE_report(op->reports, RPT_ERROR, "Unable to find valid 3D View area"); + return OPERATOR_CANCELLED; + } + View3D *v3d = get_invoke_view3d(C); + + char filename[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", filename); + + const bool use_fill = RNA_boolean_get(op->ptr, "use_fill"); + const bool use_norm_thickness = RNA_boolean_get(op->ptr, "use_normalized_thickness"); + const short select_mode = RNA_enum_get(op->ptr, "selected_object_type"); + const short frame_mode = RNA_enum_get(op->ptr, "frame_mode"); + + /* Set flags. */ + int flag = 0; + SET_FLAG_FROM_TEST(flag, use_fill, GP_EXPORT_FILL); + SET_FLAG_FROM_TEST(flag, use_norm_thickness, GP_EXPORT_NORM_THICKNESS); + + GpencilIOParams params = {.C = C, + .region = region, + .v3d = v3d, + .ob = ob, + .mode = GP_EXPORT_TO_PDF, + .frame_start = SFRA, + .frame_end = EFRA, + .frame_cur = CFRA, + .flag = flag, + .scale = 1.0f, + .select_mode = select_mode, + .frame_mode = frame_mode, + .stroke_sample = RNA_float_get(op->ptr, "stroke_sample"), + .resolution = 1.0f}; + + /* Do export. */ + WM_cursor_wait(true); + const bool done = gpencil_io_export(filename, ¶ms); + WM_cursor_wait(false); + + if (!done) { + BKE_report(op->reports, RPT_WARNING, "Unable to export PDF"); + } + + return OPERATOR_FINISHED; +} + +static void ui_gpencil_export_pdf_settings(uiLayout *layout, PointerRNA *imfptr) +{ + uiLayout *box, *row, *col, *sub; + + uiLayoutSetPropSep(layout, true); + uiLayoutSetPropDecorate(layout, false); + + box = uiLayoutBox(layout); + + row = uiLayoutRow(box, false); + uiItemL(row, IFACE_("Scene Options"), ICON_NONE); + + row = uiLayoutRow(box, false); + uiItemR(row, imfptr, "selected_object_type", 0, NULL, ICON_NONE); + + box = uiLayoutBox(layout); + row = uiLayoutRow(box, false); + uiItemL(row, IFACE_("Export Options"), ICON_NONE); + + col = uiLayoutColumn(box, false); + sub = uiLayoutColumn(col, true); + uiItemR(sub, imfptr, "frame_mode", 0, IFACE_("Frame"), ICON_NONE); + + uiLayoutSetPropSep(box, true); + + sub = uiLayoutColumn(col, true); + uiItemR(sub, imfptr, "stroke_sample", 0, NULL, ICON_NONE); + uiItemR(sub, imfptr, "use_fill", 0, NULL, ICON_NONE); + uiItemR(sub, imfptr, "use_normalized_thickness", 0, NULL, ICON_NONE); +} + +static void wm_gpencil_export_pdf_draw(bContext *UNUSED(C), wmOperator *op) +{ + PointerRNA ptr; + + RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); + + ui_gpencil_export_pdf_settings(op->layout, &ptr); +} + +static bool wm_gpencil_export_pdf_poll(bContext *C) +{ + if ((CTX_wm_window(C) == NULL) || (CTX_data_mode_enum(C) != CTX_MODE_OBJECT)) { + return false; + } + + return true; +} + +void WM_OT_gpencil_export_pdf(wmOperatorType *ot) +{ + ot->name = "Export to PDF"; + ot->description = "Export grease pencil to PDF"; + ot->idname = "WM_OT_gpencil_export_pdf"; + + ot->invoke = wm_gpencil_export_pdf_invoke; + ot->exec = wm_gpencil_export_pdf_exec; + ot->poll = wm_gpencil_export_pdf_poll; + ot->ui = wm_gpencil_export_pdf_draw; + ot->check = wm_gpencil_export_pdf_common_check; + + WM_operator_properties_filesel(ot, + FILE_TYPE_OBJECT_IO, + FILE_BLENDER, + FILE_SAVE, + WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS, + FILE_DEFAULTDISPLAY, + FILE_SORT_ALPHA); + + static const EnumPropertyItem gpencil_export_frame_items[] = { + {GP_EXPORT_FRAME_ACTIVE, "ACTIVE", 0, "Active", "Include only active frame"}, + {GP_EXPORT_FRAME_SELECTED, "SELECTED", 0, "Selected", "Include selected frames"}, + {0, NULL, 0, NULL, NULL}, + }; + + gpencil_export_common_props_definition(ot); + ot->prop = RNA_def_enum(ot->srna, + "frame_mode", + gpencil_export_frame_items, + GP_EXPORT_ACTIVE, + "Frames", + "Which frames to include in the export"); +} +#endif diff --git a/source/blender/editors/io/io_gpencil_import.c b/source/blender/editors/io/io_gpencil_import.c new file mode 100644 index 00000000000..9768da85940 --- /dev/null +++ b/source/blender/editors/io/io_gpencil_import.c @@ -0,0 +1,195 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup editor/io + */ + +#include "BLI_path_util.h" + +#include "DNA_gpencil_types.h" +#include "DNA_space_types.h" + +#include "BKE_context.h" +#include "BKE_gpencil.h" +#include "BKE_report.h" + +#include "BLT_translation.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "ED_gpencil.h" + +#include "io_gpencil.h" + +#include "gpencil_io.h" + +/* <-------- SVG single frame import. --------> */ +static bool wm_gpencil_import_svg_common_check(bContext *UNUSED(C), wmOperator *op) +{ + + char filepath[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", filepath); + + if (!BLI_path_extension_check(filepath, ".svg")) { + BLI_path_extension_ensure(filepath, FILE_MAX, ".svg"); + RNA_string_set(op->ptr, "filepath", filepath); + return true; + } + + return false; +} + +static int wm_gpencil_import_svg_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + WM_event_add_fileselect(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int wm_gpencil_import_svg_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + + if (!RNA_struct_property_is_set(op->ptr, "filepath")) { + BKE_report(op->reports, RPT_ERROR, "No filename given"); + return OPERATOR_CANCELLED; + } + + ARegion *region = get_invoke_region(C); + if (region == NULL) { + BKE_report(op->reports, RPT_ERROR, "Unable to find valid 3D View area"); + return OPERATOR_CANCELLED; + } + View3D *v3d = get_invoke_view3d(C); + + char filename[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", filename); + + /* Set flags. */ + int flag = 0; + + const int resolution = RNA_int_get(op->ptr, "resolution"); + const float scale = RNA_float_get(op->ptr, "scale"); + + GpencilIOParams params = { + .C = C, + .region = region, + .v3d = v3d, + .ob = NULL, + .mode = GP_IMPORT_FROM_SVG, + .frame_start = CFRA, + .frame_end = CFRA, + .frame_cur = CFRA, + .flag = flag, + .scale = scale, + .select_mode = 0, + .frame_mode = 0, + .stroke_sample = 0.0f, + .resolution = resolution, + }; + + /* Do Import. */ + WM_cursor_wait(1); + const bool done = gpencil_io_import(filename, ¶ms); + WM_cursor_wait(0); + + if (!done) { + BKE_report(op->reports, RPT_WARNING, "Unable to import SVG"); + } + + return OPERATOR_FINISHED; +} + +static void ui_gpencil_import_svg_settings(uiLayout *layout, PointerRNA *imfptr) +{ + uiLayoutSetPropSep(layout, true); + uiLayoutSetPropDecorate(layout, false); + uiLayout *col = uiLayoutColumn(layout, false); + uiItemR(col, imfptr, "resolution", 0, NULL, ICON_NONE); + uiItemR(col, imfptr, "scale", 0, NULL, ICON_NONE); +} + +static void wm_gpencil_import_svg_draw(bContext *UNUSED(C), wmOperator *op) +{ + PointerRNA ptr; + RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); + + ui_gpencil_import_svg_settings(op->layout, &ptr); +} + +static bool wm_gpencil_import_svg_poll(bContext *C) +{ + if ((CTX_wm_window(C) == NULL) || (CTX_data_mode_enum(C) != CTX_MODE_OBJECT)) { + return false; + } + + return true; +} + +void WM_OT_gpencil_import_svg(wmOperatorType *ot) +{ + ot->name = "Import SVG"; + ot->description = "Import SVG into grease pencil"; + ot->idname = "WM_OT_gpencil_import_svg"; + + ot->invoke = wm_gpencil_import_svg_invoke; + ot->exec = wm_gpencil_import_svg_exec; + ot->poll = wm_gpencil_import_svg_poll; + ot->ui = wm_gpencil_import_svg_draw; + ot->check = wm_gpencil_import_svg_common_check; + + WM_operator_properties_filesel(ot, + FILE_TYPE_OBJECT_IO, + FILE_BLENDER, + FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS, + FILE_DEFAULTDISPLAY, + FILE_SORT_DEFAULT); + + RNA_def_int(ot->srna, + "resolution", + 10, + 1, + 30, + "Resolution", + "Resolution of the generated strokes", + 1, + 20); + + RNA_def_float(ot->srna, + "scale", + 10.0f, + 0.001f, + 100.0f, + "Scale", + "Scale of the final strokes", + 0.001f, + 100.0f); +} diff --git a/source/blender/editors/io/io_gpencil_utils.c b/source/blender/editors/io/io_gpencil_utils.c new file mode 100644 index 00000000000..259a669519a --- /dev/null +++ b/source/blender/editors/io/io_gpencil_utils.c @@ -0,0 +1,64 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup editor/io + */ + +#include "DNA_space_types.h" + +#include "BKE_context.h" +#include "BKE_screen.h" + +#include "WM_api.h" + +#include "io_gpencil.h" + +ARegion *get_invoke_region(bContext *C) +{ + bScreen *screen = CTX_wm_screen(C); + if (screen == NULL) { + return NULL; + } + ScrArea *area = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0); + if (area == NULL) { + return NULL; + } + + ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); + + return region; +} + +View3D *get_invoke_view3d(bContext *C) +{ + bScreen *screen = CTX_wm_screen(C); + if (screen == NULL) { + return NULL; + } + ScrArea *area = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0); + if (area == NULL) { + return NULL; + } + if (area) { + return area->spacedata.first; + } + + return NULL; +} diff --git a/source/blender/editors/io/io_ops.c b/source/blender/editors/io/io_ops.c index acb511a414d..9fa34a1c55d 100644 --- a/source/blender/editors/io/io_ops.c +++ b/source/blender/editors/io/io_ops.c @@ -38,6 +38,7 @@ #endif #include "io_cache.h" +#include "io_gpencil.h" void ED_operatortypes_io(void) { @@ -54,6 +55,16 @@ void ED_operatortypes_io(void) WM_operatortype_append(WM_OT_usd_export); #endif + WM_operatortype_append(WM_OT_gpencil_import_svg); + +#ifdef WITH_PUGIXML + WM_operatortype_append(WM_OT_gpencil_export_svg); +#endif + +#ifdef WITH_HARU + WM_operatortype_append(WM_OT_gpencil_export_pdf); +#endif + WM_operatortype_append(CACHEFILE_OT_open); WM_operatortype_append(CACHEFILE_OT_reload); } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index e4527740164..50dc1af5ca8 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1440,41 +1440,6 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static const EnumPropertyItem *object_gpencil_add_options(bContext *C, - PointerRNA *UNUSED(ptr), - PropertyRNA *UNUSED(prop), - bool *r_free) -{ - EnumPropertyItem *item = NULL; - const EnumPropertyItem *item_ref = rna_enum_object_gpencil_type_items; - int totitem = 0; - int i = 0; - int orig_count = RNA_enum_items_count(item_ref); - - /* Default types. */ - for (i = 0; i < orig_count; i++) { - if (item_ref[i].value == GP_LRT_OBJECT || item_ref[i].value == GP_LRT_COLLECTION || - item_ref[i].value == GP_LRT_SCENE) { - if (item_ref[i].value == GP_LRT_SCENE) { - /* separator before line art types */ - RNA_enum_item_add_separator(&item, &totitem); - } - else if (item_ref[i].value == GP_LRT_OBJECT) { - Object *ob = CTX_data_active_object(C); - if (!ob || ob->type != OB_MESH) { - continue; - } - } - } - RNA_enum_item_add(&item, &totitem, &item_ref[i]); - } - - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; -} - void OBJECT_OT_gpencil_add(wmOperatorType *ot) { /* identifiers */ @@ -1495,7 +1460,6 @@ void OBJECT_OT_gpencil_add(wmOperatorType *ot) ED_object_add_generic_props(ot, false); ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_object_gpencil_type_items, 0, "Type", ""); - RNA_def_enum_funcs(ot->prop, object_gpencil_add_options); } /** \} */ diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index f5ec9a0e8a1..4c9f80bfa64 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -2543,7 +2543,7 @@ int ED_path_extension_type(const char *path) if (BLI_path_extension_check(path, ".zip")) { return FILE_TYPE_ARCHIVE; } - if (BLI_path_extension_check_n(path, ".obj", ".3ds", ".fbx", ".glb", ".gltf", NULL)) { + if (BLI_path_extension_check_n(path, ".obj", ".3ds", ".fbx", ".glb", ".gltf", ".svg", NULL)) { return FILE_TYPE_OBJECT_IO; } if (BLI_path_extension_check_array(path, imb_ext_image)) { diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 1354c06305c..6864d34885a 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3429,13 +3429,13 @@ static void std_node_socket_draw( } break; case SOCK_RGBA: { - uiLayout *row = uiLayoutSplit(layout, 0.5f, false); + uiLayout *row = uiLayoutSplit(layout, 0.4f, false); uiItemL(row, text, 0); uiItemR(row, ptr, "default_value", DEFAULT_FLAGS, "", 0); break; } case SOCK_STRING: { - uiLayout *row = uiLayoutSplit(layout, 0.5f, false); + uiLayout *row = uiLayoutSplit(layout, 0.4f, false); uiItemL(row, text, 0); const bNodeTree *node_tree = (const bNodeTree *)node_ptr->owner_id; diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index a646804e0fd..c4fe9e9e531 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -472,6 +472,8 @@ static int node_add_object_exec(bContext *C, wmOperator *op) snode_notify(C, snode); snode_dag_update(C, snode); + ED_node_tag_update_nodetree(bmain, ntree, object_node); + return OPERATOR_FINISHED; } @@ -496,7 +498,8 @@ static int node_add_object_invoke(bContext *C, wmOperator *op, const wmEvent *ev static bool node_add_object_poll(bContext *C) { const SpaceNode *snode = CTX_wm_space_node(C); - return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY); + return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY) && + !UI_but_active_drop_name(C); } void NODE_OT_add_object(wmOperatorType *ot) @@ -568,6 +571,8 @@ static int node_add_texture_exec(bContext *C, wmOperator *op) snode_notify(C, snode); snode_dag_update(C, snode); + ED_node_tag_update_nodetree(bmain, ntree, texture_node); + return OPERATOR_FINISHED; } @@ -592,7 +597,8 @@ static int node_add_texture_invoke(bContext *C, wmOperator *op, const wmEvent *e static bool node_add_texture_poll(bContext *C) { const SpaceNode *snode = CTX_wm_space_node(C); - return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY); + return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY) && + !UI_but_active_drop_name(C); } void NODE_OT_add_texture(wmOperatorType *ot) @@ -670,6 +676,8 @@ static int node_add_collection_exec(bContext *C, wmOperator *op) snode_notify(C, snode); snode_dag_update(C, snode); + ED_node_tag_update_nodetree(bmain, ntree, collection_node); + return OPERATOR_FINISHED; } @@ -694,7 +702,8 @@ static int node_add_collection_invoke(bContext *C, wmOperator *op, const wmEvent static bool node_add_collection_poll(bContext *C) { const SpaceNode *snode = CTX_wm_space_node(C); - return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY); + return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY) && + !UI_but_active_drop_name(C); } void NODE_OT_add_collection(wmOperatorType *ot) diff --git a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc index 89c9960a24f..f00cf3c34c0 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc @@ -148,6 +148,14 @@ void TreeDisplayViewLayer::add_layer_collections_recursive(ListBase &tree, if (!exclude && show_objects_) { add_layer_collection_objects(ten->subtree, *lc, *ten); } + + const bool lib_overrides_visible = !SUPPORT_FILTER_OUTLINER(&space_outliner_) || + ((space_outliner_.filter & SO_FILTER_NO_LIB_OVERRIDE) == 0); + + if (lib_overrides_visible && ID_IS_OVERRIDE_LIBRARY_REAL(&lc->collection->id)) { + outliner_add_element( + &space_outliner_, &ten->subtree, &lc->collection->id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0); + } } } diff --git a/source/blender/editors/space_outliner/tree/tree_element_overrides.hh b/source/blender/editors/space_outliner/tree/tree_element_overrides.hh index b5c772f5b33..4f7025610ed 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_overrides.hh +++ b/source/blender/editors/space_outliner/tree/tree_element_overrides.hh @@ -39,7 +39,7 @@ class TreeElementOverridesBase final : public AbstractTreeElement { }; class TreeElementOverridesProperty final : public AbstractTreeElement { - ID &id_; + [[maybe_unused]] ID &id_; IDOverrideLibraryProperty &override_prop_; public: diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index 7270763c4e4..93c36645873 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -60,127 +60,133 @@ void transform_convert_mesh_islands_calc(struct BMEditMesh *em, const bool calc_island_axismtx, struct TransIslandData *r_island_data) { + struct TransIslandData data = {NULL}; + BMesh *bm = em->bm; char htype; char itype; int i; /* group vars */ - float(*center)[3] = NULL; - float(*axismtx)[3][3] = NULL; - int *groups_array; - int(*group_index)[2]; - int group_tot; - void **ele_array; + int *groups_array = NULL; + int(*group_index)[2] = NULL; - int *vert_map; + bool has_only_single_islands = bm->totedgesel == 0 && bm->totfacesel == 0; + if (has_only_single_islands && !calc_single_islands) { + return; + } - if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) { - groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__); - group_tot = BM_mesh_calc_edge_groups( - bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT); + data.island_vert_map = MEM_mallocN(sizeof(*data.island_vert_map) * bm->totvert, __func__); + /* we shouldn't need this, but with incorrect selection flushing + * its possible we have a selected vertex that's not in a face, + * for now best not crash in that case. */ + copy_vn_i(data.island_vert_map, bm->totvert, -1); - htype = BM_EDGE; - itype = BM_VERTS_OF_EDGE; - } - else { /* (bm->selectmode & SCE_SELECT_FACE) */ - groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__); - group_tot = BM_mesh_calc_face_groups( - bm, groups_array, &group_index, NULL, NULL, NULL, BM_ELEM_SELECT, BM_VERT); + if (!has_only_single_islands) { + if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) { + groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__); + data.island_tot = BM_mesh_calc_edge_groups( + bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT); - htype = BM_FACE; - itype = BM_VERTS_OF_FACE; - } + htype = BM_EDGE; + itype = BM_VERTS_OF_EDGE; + } + else { /* (bm->selectmode & SCE_SELECT_FACE) */ + groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__); + data.island_tot = BM_mesh_calc_face_groups( + bm, groups_array, &group_index, NULL, NULL, NULL, BM_ELEM_SELECT, BM_VERT); - if (calc_island_center) { - center = MEM_mallocN(sizeof(*center) * group_tot, __func__); - } + htype = BM_FACE; + itype = BM_VERTS_OF_FACE; + } - if (calc_island_axismtx) { - axismtx = MEM_mallocN(sizeof(*axismtx) * group_tot, __func__); - } + BLI_assert(data.island_tot); + if (calc_island_center) { + data.center = MEM_mallocN(sizeof(*data.center) * data.island_tot, __func__); + } - vert_map = MEM_mallocN(sizeof(*vert_map) * bm->totvert, __func__); - /* we shouldn't need this, but with incorrect selection flushing - * its possible we have a selected vertex that's not in a face, - * for now best not crash in that case. */ - copy_vn_i(vert_map, bm->totvert, -1); + if (calc_island_axismtx) { + data.axismtx = MEM_mallocN(sizeof(*data.axismtx) * data.island_tot, __func__); + } - BM_mesh_elem_table_ensure(bm, htype); - ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable; + BM_mesh_elem_table_ensure(bm, htype); - BM_mesh_elem_index_ensure(bm, BM_VERT); + void **ele_array; + ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable; - /* may be an edge OR a face array */ - for (i = 0; i < group_tot; i++) { - BMEditSelection ese = {NULL}; + BM_mesh_elem_index_ensure(bm, BM_VERT); - const int fg_sta = group_index[i][0]; - const int fg_len = group_index[i][1]; - float co[3], no[3], tangent[3]; - int j; + /* may be an edge OR a face array */ + for (i = 0; i < data.island_tot; i++) { + BMEditSelection ese = {NULL}; - zero_v3(co); - zero_v3(no); - zero_v3(tangent); + const int fg_sta = group_index[i][0]; + const int fg_len = group_index[i][1]; + float co[3], no[3], tangent[3]; + int j; - ese.htype = htype; + zero_v3(co); + zero_v3(no); + zero_v3(tangent); - /* loop on each face or edge in this group: - * - assign r_vert_map - * - calculate (co, no) - */ - for (j = 0; j < fg_len; j++) { - ese.ele = ele_array[groups_array[fg_sta + j]]; + ese.htype = htype; - if (center) { - float tmp_co[3]; - BM_editselection_center(&ese, tmp_co); - add_v3_v3(co, tmp_co); - } + /* loop on each face or edge in this group: + * - assign r_vert_map + * - calculate (co, no) + */ + for (j = 0; j < fg_len; j++) { + ese.ele = ele_array[groups_array[fg_sta + j]]; - if (axismtx) { - float tmp_no[3], tmp_tangent[3]; - BM_editselection_normal(&ese, tmp_no); - BM_editselection_plane(&ese, tmp_tangent); - add_v3_v3(no, tmp_no); - add_v3_v3(tangent, tmp_tangent); - } + if (data.center) { + float tmp_co[3]; + BM_editselection_center(&ese, tmp_co); + add_v3_v3(co, tmp_co); + } - { - /* setup vertex map */ - BMIter iter; - BMVert *v; + if (data.axismtx) { + float tmp_no[3], tmp_tangent[3]; + BM_editselection_normal(&ese, tmp_no); + BM_editselection_plane(&ese, tmp_tangent); + add_v3_v3(no, tmp_no); + add_v3_v3(tangent, tmp_tangent); + } - /* connected edge-verts */ - BM_ITER_ELEM (v, &iter, ese.ele, itype) { - vert_map[BM_elem_index_get(v)] = i; + { + /* setup vertex map */ + BMIter iter; + BMVert *v; + + /* connected edge-verts */ + BM_ITER_ELEM (v, &iter, ese.ele, itype) { + data.island_vert_map[BM_elem_index_get(v)] = i; + } } } - } - if (center) { - mul_v3_v3fl(center[i], co, 1.0f / (float)fg_len); - } - - if (axismtx) { - if (createSpaceNormalTangent(axismtx[i], no, tangent)) { - /* pass */ + if (data.center) { + mul_v3_v3fl(data.center[i], co, 1.0f / (float)fg_len); } - else { - if (normalize_v3(no) != 0.0f) { - axis_dominant_v3_to_m3(axismtx[i], no); - invert_m3(axismtx[i]); + + if (data.axismtx) { + if (createSpaceNormalTangent(data.axismtx[i], no, tangent)) { + /* pass */ } else { - unit_m3(axismtx[i]); + if (normalize_v3(no) != 0.0f) { + axis_dominant_v3_to_m3(data.axismtx[i], no); + invert_m3(data.axismtx[i]); + } + else { + unit_m3(data.axismtx[i]); + } } } } - } - MEM_freeN(groups_array); - MEM_freeN(group_index); + MEM_freeN(groups_array); + MEM_freeN(group_index); + } /* for PET we need islands of 1 so connected vertices can use it with V3D_AROUND_LOCAL_ORIGINS */ if (calc_single_islands) { @@ -189,45 +195,44 @@ void transform_convert_mesh_islands_calc(struct BMEditMesh *em, int group_tot_single = 0; BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) { - if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) { + if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (data.island_vert_map[i] == -1)) { group_tot_single += 1; } } if (group_tot_single != 0) { - if (center) { - center = MEM_reallocN(center, sizeof(*center) * (group_tot + group_tot_single)); + if (calc_island_center) { + data.center = MEM_reallocN(data.center, + sizeof(*data.center) * (data.island_tot + group_tot_single)); } - if (axismtx) { - axismtx = MEM_reallocN(axismtx, sizeof(*axismtx) * (group_tot + group_tot_single)); + if (calc_island_axismtx) { + data.axismtx = MEM_reallocN(data.axismtx, + sizeof(*data.axismtx) * (data.island_tot + group_tot_single)); } BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) { - if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) { - vert_map[i] = group_tot; - if (center) { - copy_v3_v3(center[group_tot], v->co); + if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (data.island_vert_map[i] == -1)) { + data.island_vert_map[i] = data.island_tot; + if (data.center) { + copy_v3_v3(data.center[data.island_tot], v->co); } - if (axismtx) { - if (is_zero_v3(v->no) != 0.0f) { - axis_dominant_v3_to_m3(axismtx[group_tot], v->no); - invert_m3(axismtx[group_tot]); + if (data.axismtx) { + if (is_zero_v3(v->no) == false) { + axis_dominant_v3_to_m3(data.axismtx[data.island_tot], v->no); + invert_m3(data.axismtx[data.island_tot]); } else { - unit_m3(axismtx[group_tot]); + unit_m3(data.axismtx[data.island_tot]); } } - group_tot += 1; + data.island_tot += 1; } } } } - r_island_data->axismtx = axismtx; - r_island_data->center = center; - r_island_data->island_tot = group_tot; - r_island_data->island_vert_map = vert_map; + *r_island_data = data; } void transform_convert_mesh_islanddata_free(struct TransIslandData *island_data) diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 9903711834a..da94eef4917 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -146,7 +146,7 @@ void ED_editors_init(bContext *C) ED_object_wpaintmode_enter_ex(bmain, depsgraph, scene, ob); } else { - BLI_assert(0); + BLI_assert_unreachable(); } } else { diff --git a/source/blender/editors/util/select_utils.c b/source/blender/editors/util/select_utils.c index 85f48e6d397..14a6d751bb1 100644 --- a/source/blender/editors/util/select_utils.c +++ b/source/blender/editors/util/select_utils.c @@ -94,7 +94,7 @@ int ED_select_similar_compare_float(const float delta, const float thresh, const case SIM_CMP_LT: return ((delta - thresh) < FLT_EPSILON); default: - BLI_assert(0); + BLI_assert_unreachable(); return 0; } } @@ -124,7 +124,7 @@ bool ED_select_similar_compare_float_tree(const KDTree_1d *tree, nearest_edge_length = FLT_MAX; break; default: - BLI_assert(0); + BLI_assert_unreachable(); return false; } diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c index c8aa21191ba..e1b9a287457 100644 --- a/source/blender/editors/uvedit/uvedit_rip.c +++ b/source/blender/editors/uvedit/uvedit_rip.c @@ -169,7 +169,7 @@ static BMLoop *bm_loop_find_other_fan_loop_with_visible_face(BMLoop *l_src, l_other = l_other->prev; } else { - BLI_assert(0); + BLI_assert_unreachable(); } } return l_other; @@ -189,7 +189,7 @@ static BMLoop *bm_vert_step_fan_loop_uv(BMLoop *l, BMEdge **e_step, const int cd l_next = l; } else { - BLI_assert(0); + BLI_assert_unreachable(); return NULL; } diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index f46975c9378..c10e132a4e2 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -2213,7 +2213,7 @@ static int uv_mouse_select_loop_generic_multi(bContext *C, flush = uv_select_edgering(sima, scene, obedit, &hit, extend); } else { - BLI_assert(0); + BLI_assert_unreachable(); } if (ts->uv_flag & UV_SYNC_SELECTION) { diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c index 4efc1d9eaae..2934b89c747 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c @@ -136,36 +136,39 @@ static void bakeModifier(Main *UNUSED(bmain), bGPdata *gpd = ob->data; int oldframe = (int)DEG_get_ctime(depsgraph); - if (mmd->object == NULL) { + if ((mmd->object == NULL) || (mmd->object->type != OB_LATTICE)) { return; } LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { - /* apply lattice effects on this frame - * NOTE: this assumes that we don't want lattice animation on non-keyframed frames + /* Apply lattice effects on this frame + * NOTE: this assumes that we don't want lattice animation on non-keyframed frames. */ CFRA = gpf->framenum; BKE_scene_graph_update_for_newframe(depsgraph); - /* recalculate lattice data */ - BKE_gpencil_lattice_init(ob); + /* Recalculate lattice data. */ + if (mmd->cache_data) { + BKE_lattice_deform_data_destroy(mmd->cache_data); + } + mmd->cache_data = BKE_lattice_deform_data_create(mmd->object, ob); - /* compute lattice effects on this frame */ + /* Compute lattice effects on this frame. */ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { deformStroke(md, depsgraph, ob, gpl, gpf, gps); } } } - /* free lingering data */ + /* Free lingering data. */ ldata = (struct LatticeDeformData *)mmd->cache_data; if (ldata) { BKE_lattice_deform_data_destroy(ldata); mmd->cache_data = NULL; } - /* return frame state and DB to original state */ + /* Return frame state and DB to original state. */ CFRA = oldframe; BKE_scene_graph_update_for_newframe(depsgraph); } diff --git a/source/blender/gpu/intern/gpu_material_library.c b/source/blender/gpu/intern/gpu_material_library.c index 64cd375d466..175facc0a8d 100644 --- a/source/blender/gpu/intern/gpu_material_library.c +++ b/source/blender/gpu/intern/gpu_material_library.c @@ -23,6 +23,7 @@ * GPU material library parsing and code generation. */ +#include <stdio.h> #include <string.h> #include "MEM_guardedalloc.h" diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c index bf91a5bbb4d..b220c60e979 100644 --- a/source/blender/gpu/intern/gpu_node_graph.c +++ b/source/blender/gpu/intern/gpu_node_graph.c @@ -23,6 +23,7 @@ * Intermediate node graph for generating GLSL shaders. */ +#include <stdio.h> #include <string.h> #include "MEM_guardedalloc.h" diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 0d2080b5f0a..61bc185eb8d 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -393,7 +393,7 @@ static ImBuf *thumb_create_ex(const char *file_path, img = IMB_thumb_load_font(file_path, tsize, tsize); break; default: - BLI_assert(0); /* This should never happen */ + BLI_assert_unreachable(); /* This should never happen */ } } @@ -738,7 +738,7 @@ void IMB_thumb_path_unlock(const char *path) if (thumb_locks.locked_paths) { if (!BLI_gset_remove(thumb_locks.locked_paths, key, MEM_freeN)) { - BLI_assert(0); + BLI_assert_unreachable(); } BLI_condition_notify_all(&thumb_locks.cond); } diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c index 106e4618847..b7b31b3e56a 100644 --- a/source/blender/imbuf/intern/thumbs_blend.c +++ b/source/blender/imbuf/intern/thumbs_blend.c @@ -18,6 +18,7 @@ * \ingroup imbuf */ +#include <stdio.h> #include <stdlib.h> #include <string.h> diff --git a/source/blender/io/CMakeLists.txt b/source/blender/io/CMakeLists.txt index 360cacc4360..f11ad7627b9 100644 --- a/source/blender/io/CMakeLists.txt +++ b/source/blender/io/CMakeLists.txt @@ -35,3 +35,5 @@ endif() if(WITH_USD) add_subdirectory(usd) endif() + +add_subdirectory(gpencil) diff --git a/source/blender/io/collada/Materials.cpp b/source/blender/io/collada/Materials.cpp index 644ecc18e9b..6ba31599fcd 100644 --- a/source/blender/io/collada/Materials.cpp +++ b/source/blender/io/collada/Materials.cpp @@ -25,6 +25,8 @@ MaterialNode::MaterialNode(bContext *C, Material *ma, KeyImageMap &key_image_map shader_node = add_node(SH_NODE_BSDF_PRINCIPLED, 0, 300, ""); output_node = add_node(SH_NODE_OUTPUT_MATERIAL, 300, 300, ""); add_link(shader_node, 0, output_node, 0); + + ntreeUpdateTree(CTX_data_main(C), ntree); } } @@ -59,6 +61,8 @@ MaterialNode::MaterialNode(bContext *C, shader_node = add_node(SH_NODE_BSDF_PRINCIPLED, 0, 300, ""); output_node = add_node(SH_NODE_OUTPUT_MATERIAL, 300, 300, ""); add_link(shader_node, 0, output_node, 0); + + ntreeUpdateTree(CTX_data_main(C), ntree); #endif } diff --git a/source/blender/io/gpencil/CMakeLists.txt b/source/blender/io/gpencil/CMakeLists.txt new file mode 100644 index 00000000000..11c9affbe5a --- /dev/null +++ b/source/blender/io/gpencil/CMakeLists.txt @@ -0,0 +1,99 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# ***** END GPL LICENSE BLOCK ***** + +set(INC + . + ../common + ../../blenkernel + ../../blenlib + ../../blenloader + ../../bmesh + ../../depsgraph + ../../editors/include + ../../makesdna + ../../makesrna + ../../windowmanager + ../../../../intern/clog + ../../../../intern/guardedalloc + ../../../../intern/utfconv +) + +set(INC_SYS +) + +set(SRC + intern/gpencil_io_capi.cc + + # This line must be removed if NanoSVG is moved to extern + nanosvg/nanosvg.h + + gpencil_io.h + + intern/gpencil_io_base.h + intern/gpencil_io_base.cc + + intern/gpencil_io_import_base.h + intern/gpencil_io_import_svg.h + intern/gpencil_io_import_base.cc + intern/gpencil_io_import_svg.cc + + intern/gpencil_io_export_base.h +) + +set(LIB + bf_blenkernel + bf_blenlib + bf_io_common +) + +if(WITH_PUGIXML) + list(APPEND SRC + intern/gpencil_io_export_svg.h + intern/gpencil_io_export_svg.cc + ) + list(APPEND INC_SYS + ${PUGIXML_INCLUDE_DIR} + ) + list(APPEND LIB + ${PUGIXML_LIBRARIES} + ) + add_definitions(-DWITH_PUGIXML) +endif() + +if(WITH_HARU) + list(APPEND SRC + intern/gpencil_io_export_pdf.h + intern/gpencil_io_export_pdf.cc + ) + list(APPEND INC_SYS + ${HARU_INCLUDE_DIRS} + ) + list(APPEND LIB + ${HARU_LIBRARIES} + ) + add_definitions(-DWITH_HARU) +endif() + + +list(APPEND LIB + ${BOOST_LIBRARIES} +) + +blender_add_lib(bf_gpencil "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/io/gpencil/gpencil_io.h b/source/blender/io/gpencil/gpencil_io.h new file mode 100644 index 00000000000..f4b2e59f8c5 --- /dev/null +++ b/source/blender/io/gpencil/gpencil_io.h @@ -0,0 +1,92 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ +#pragma once + +/** \file + * \ingroup bgpencil + */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct ARegion; +struct bContext; +struct Object; +struct View3D; + +typedef struct GpencilIOParams { + bContext *C; + ARegion *region; + View3D *v3d; + /** Grease pencil object. */ + Object *ob; + /** Mode (see eGpencilIO_Modes). */ + uint16_t mode; + int32_t frame_start; + int32_t frame_end; + int32_t frame_cur; + uint32_t flag; + float scale; + /** Select mode (see eGpencilExportSelect). */ + uint16_t select_mode; + /** Frame mode (see eGpencilExportFrame). */ + uint16_t frame_mode; + /** Stroke sampling factor. */ + float stroke_sample; + int32_t resolution; +} GpencilIOParams; + +/* GpencilIOParams->flag. */ +typedef enum eGpencilIOParams_Flag { + /* Export Filled strokes. */ + GP_EXPORT_FILL = (1 << 0), + /* Export normalized thickness. */ + GP_EXPORT_NORM_THICKNESS = (1 << 1), + /* Clip camera area. */ + GP_EXPORT_CLIP_CAMERA = (1 << 2), +} eGpencilIOParams_Flag; + +typedef enum eGpencilIO_Modes { + GP_EXPORT_TO_SVG = 0, + GP_EXPORT_TO_PDF = 1, + + GP_IMPORT_FROM_SVG = 2, + /* Add new formats here. */ +} eGpencilIO_Modes; + +/* Object to be exported. */ +typedef enum eGpencilExportSelect { + GP_EXPORT_ACTIVE = 0, + GP_EXPORT_SELECTED = 1, + GP_EXPORT_VISIBLE = 2, +} eGpencilExportSelect; + +/* Framerange to be exported. */ +typedef enum eGpencilExportFrame { + GP_EXPORT_FRAME_ACTIVE = 0, + GP_EXPORT_FRAME_SELECTED = 1, +} eGpencilExportFrame; + +bool gpencil_io_export(const char *filename, struct GpencilIOParams *iparams); +bool gpencil_io_import(const char *filename, struct GpencilIOParams *iparams); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.cc b/source/blender/io/gpencil/intern/gpencil_io_base.cc new file mode 100644 index 00000000000..855252e648c --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_base.cc @@ -0,0 +1,386 @@ + + +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ + +/** \file + * \ingroup bgpencil + */ + +#include "BLI_float2.hh" +#include "BLI_float3.hh" +#include "BLI_float4x4.hh" +#include "BLI_path_util.h" +#include "BLI_span.hh" + +#include "DNA_gpencil_types.h" +#include "DNA_layer_types.h" +#include "DNA_material_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" + +#include "BKE_camera.h" +#include "BKE_context.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_geom.h" +#include "BKE_main.h" +#include "BKE_material.h" + +#include "UI_view2d.h" + +#include "ED_view3d.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "gpencil_io_base.h" + +using blender::Span; + +namespace blender::io::gpencil { + +/* Constructor. */ +GpencilIO::GpencilIO(const GpencilIOParams *iparams) +{ + params_ = *iparams; + + /* Easy access data. */ + bmain_ = CTX_data_main(params_.C); + depsgraph_ = CTX_data_depsgraph_pointer(params_.C); + scene_ = CTX_data_scene(params_.C); + rv3d_ = (RegionView3D *)params_.region->regiondata; + gpd_ = (params_.ob != nullptr) ? (bGPdata *)params_.ob->data : nullptr; + cfra_ = iparams->frame_cur; + + /* Calculate camera matrix. */ + Object *cam_ob = params_.v3d->camera; + if (cam_ob != nullptr) { + /* Set up parameters. */ + CameraParams params; + BKE_camera_params_init(¶ms); + BKE_camera_params_from_object(¶ms, cam_ob); + + /* Compute matrix, viewplane, .. */ + RenderData *rd = &scene_->r; + BKE_camera_params_compute_viewplane(¶ms, rd->xsch, rd->ysch, rd->xasp, rd->yasp); + BKE_camera_params_compute_matrix(¶ms); + + float viewmat[4][4]; + invert_m4_m4(viewmat, cam_ob->obmat); + + mul_m4_m4m4(persmat_, params.winmat, viewmat); + } + else { + unit_m4(persmat_); + } + + winx_ = params_.region->winx; + winy_ = params_.region->winy; + + /* Camera rectangle. */ + if (rv3d_->persp == RV3D_CAMOB) { + render_x_ = (scene_->r.xsch * scene_->r.size) / 100; + render_y_ = (scene_->r.ysch * scene_->r.size) / 100; + + ED_view3d_calc_camera_border(CTX_data_scene(params_.C), + depsgraph_, + params_.region, + params_.v3d, + rv3d_, + &camera_rect_, + true); + is_camera_ = true; + camera_ratio_ = render_x_ / (camera_rect_.xmax - camera_rect_.xmin); + offset_.x = camera_rect_.xmin; + offset_.y = camera_rect_.ymin; + } + else { + is_camera_ = false; + /* Calc selected object boundbox. Need set initial value to some variables. */ + camera_ratio_ = 1.0f; + offset_.x = 0.0f; + offset_.y = 0.0f; + + selected_objects_boundbox_calc(); + rctf boundbox; + selected_objects_boundbox_get(&boundbox); + + render_x_ = boundbox.xmax - boundbox.xmin; + render_y_ = boundbox.ymax - boundbox.ymin; + offset_.x = boundbox.xmin; + offset_.y = boundbox.ymin; + } +} + +/** Create a list of selected objects sorted from back to front */ +void GpencilIO::create_object_list() +{ + ViewLayer *view_layer = CTX_data_view_layer(params_.C); + + float3 camera_z_axis; + copy_v3_v3(camera_z_axis, rv3d_->viewinv[2]); + ob_list_.clear(); + + LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { + Object *object = base->object; + + if (object->type != OB_GPENCIL) { + continue; + } + if ((params_.select_mode == GP_EXPORT_ACTIVE) && (params_.ob != object)) { + continue; + } + + if ((params_.select_mode == GP_EXPORT_SELECTED) && ((base->flag & BASE_SELECTED) == 0)) { + continue; + } + + /* Save z-depth from view to sort from back to front. */ + if (is_camera_) { + float camera_z = dot_v3v3(camera_z_axis, object->obmat[3]); + ObjectZ obz = {camera_z, object}; + ob_list_.append(obz); + } + else { + float zdepth = 0; + if (rv3d_) { + if (rv3d_->is_persp) { + zdepth = ED_view3d_calc_zfac(rv3d_, object->obmat[3], nullptr); + } + else { + zdepth = -dot_v3v3(rv3d_->viewinv[2], object->obmat[3]); + } + ObjectZ obz = {zdepth * -1.0f, object}; + ob_list_.append(obz); + } + } + } + /* Sort list of objects from point of view. */ + std::sort(ob_list_.begin(), ob_list_.end(), [](const ObjectZ &obz1, const ObjectZ &obz2) { + return obz1.zdepth < obz2.zdepth; + }); +} + +/** + * Set file input_text full path. + * \param filename: Path of the file provided by save dialog. + */ +void GpencilIO::filename_set(const char *filename) +{ + BLI_strncpy(filename_, filename, FILE_MAX); + BLI_path_abs(filename_, BKE_main_blendfile_path(bmain_)); +} + +/** Convert to screenspace. */ +bool GpencilIO::gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co) +{ + float3 parent_co = diff_mat_ * co; + float2 screen_co; + eV3DProjTest test = (eV3DProjTest)(V3D_PROJ_RET_OK); + if (ED_view3d_project_float_global(params_.region, parent_co, screen_co, test) == + V3D_PROJ_RET_OK) { + if (!ELEM(V2D_IS_CLIPPED, screen_co[0], screen_co[1])) { + copy_v2_v2(r_co, screen_co); + /* Invert X axis. */ + if (invert_axis_[0]) { + r_co[0] = winx_ - r_co[0]; + } + /* Invert Y axis. */ + if (invert_axis_[1]) { + r_co[1] = winy_ - r_co[1]; + } + /* Apply offset and scale. */ + sub_v2_v2(r_co, &offset_.x); + mul_v2_fl(r_co, camera_ratio_); + + return true; + } + } + r_co[0] = V2D_IS_CLIPPED; + r_co[1] = V2D_IS_CLIPPED; + + /* Invert X axis. */ + if (invert_axis_[0]) { + r_co[0] = winx_ - r_co[0]; + } + /* Invert Y axis. */ + if (invert_axis_[1]) { + r_co[1] = winy_ - r_co[1]; + } + + return false; +} + +/** Convert to render space. */ +float2 GpencilIO::gpencil_3D_point_to_render_space(const float3 co) +{ + float3 parent_co = diff_mat_ * co; + mul_m4_v3(persmat_, parent_co); + + parent_co.x = parent_co.x / max_ff(FLT_MIN, parent_co[2]); + parent_co.y = parent_co.y / max_ff(FLT_MIN, parent_co[2]); + + float2 r_co; + r_co.x = (parent_co.x + 1.0f) / 2.0f * (float)render_x_; + r_co.y = (parent_co.y + 1.0f) / 2.0f * (float)render_y_; + + /* Invert X axis. */ + if (invert_axis_[0]) { + r_co.x = (float)render_x_ - r_co.x; + } + /* Invert Y axis. */ + if (invert_axis_[1]) { + r_co.y = (float)render_y_ - r_co.y; + } + + return r_co; +} + +/** Convert to 2D. */ +float2 GpencilIO::gpencil_3D_point_to_2D(const float3 co) +{ + const bool is_camera = (bool)(rv3d_->persp == RV3D_CAMOB); + if (is_camera) { + return gpencil_3D_point_to_render_space(co); + } + float2 result; + gpencil_3D_point_to_screen_space(co, result); + return result; +} + +/** Get radius of point. */ +float GpencilIO::stroke_point_radius_get(bGPDlayer *gpl, bGPDstroke *gps) +{ + bGPDspoint *pt = &gps->points[0]; + const float2 screen_co = gpencil_3D_point_to_2D(&pt->x); + + /* Radius. */ + bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view( + rv3d_, gpd_, gpl, gps, 3, diff_mat_.values); + + pt = &gps_perimeter->points[0]; + const float2 screen_ex = gpencil_3D_point_to_2D(&pt->x); + + const float2 v1 = screen_co - screen_ex; + float radius = v1.length(); + BKE_gpencil_free_stroke(gps_perimeter); + + return MAX2(radius, 1.0f); +} + +void GpencilIO::prepare_layer_export_matrix(Object *ob, bGPDlayer *gpl) +{ + BKE_gpencil_layer_transform_matrix_get(depsgraph_, ob, gpl, diff_mat_.values); + diff_mat_ = diff_mat_ * float4x4(gpl->layer_invmat); +} + +void GpencilIO::prepare_stroke_export_colors(Object *ob, bGPDstroke *gps) +{ + MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1); + + /* Stroke color. */ + copy_v4_v4(stroke_color_, gp_style->stroke_rgba); + avg_opacity_ = 0; + /* Get average vertex color and apply. */ + float avg_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + for (const bGPDspoint &pt : Span(gps->points, gps->totpoints)) { + add_v4_v4(avg_color, pt.vert_color); + avg_opacity_ += pt.strength; + } + + mul_v4_v4fl(avg_color, avg_color, 1.0f / (float)gps->totpoints); + interp_v3_v3v3(stroke_color_, stroke_color_, avg_color, avg_color[3]); + avg_opacity_ /= (float)gps->totpoints; + + /* Fill color. */ + copy_v4_v4(fill_color_, gp_style->fill_rgba); + /* Apply vertex color for fill. */ + interp_v3_v3v3(fill_color_, fill_color_, gps->vert_color_fill, gps->vert_color_fill[3]); +} + +float GpencilIO::stroke_average_opacity_get() +{ + return avg_opacity_; +} + +bool GpencilIO::is_camera_mode() +{ + return is_camera_; +} + +/* Calculate selected strokes boundbox. */ +void GpencilIO::selected_objects_boundbox_calc() +{ + const float gap = 10.0f; + + float2 min, max; + INIT_MINMAX2(min, max); + + for (ObjectZ &obz : ob_list_) { + Object *ob = obz.ob; + /* Use evaluated version to get strokes with modifiers. */ + Object *ob_eval = (Object *)DEG_get_evaluated_id(depsgraph_, &ob->id); + bGPdata *gpd_eval = (bGPdata *)ob_eval->data; + + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_eval->layers) { + if (gpl->flag & GP_LAYER_HIDE) { + continue; + } + BKE_gpencil_layer_transform_matrix_get(depsgraph_, ob_eval, gpl, diff_mat_.values); + + bGPDframe *gpf = gpl->actframe; + if (gpf == nullptr) { + continue; + } + + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + if (gps->totpoints == 0) { + continue; + } + for (const bGPDspoint &pt : MutableSpan(gps->points, gps->totpoints)) { + const float2 screen_co = gpencil_3D_point_to_2D(&pt.x); + minmax_v2v2_v2(min, max, screen_co); + } + } + } + } + /* Add small gap. */ + add_v2_fl(min, gap * -1.0f); + add_v2_fl(max, gap); + + select_boundbox_.xmin = min[0]; + select_boundbox_.ymin = min[1]; + select_boundbox_.xmax = max[0]; + select_boundbox_.ymax = max[1]; +} + +void GpencilIO::selected_objects_boundbox_get(rctf *boundbox) +{ + boundbox->xmin = select_boundbox_.xmin; + boundbox->xmax = select_boundbox_.xmax; + boundbox->ymin = select_boundbox_.ymin; + boundbox->ymax = select_boundbox_.ymax; +} + +void GpencilIO::frame_number_set(const int value) +{ + cfra_ = value; +} + +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.h b/source/blender/io/gpencil/intern/gpencil_io_base.h new file mode 100644 index 00000000000..986221618b7 --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_base.h @@ -0,0 +1,116 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ +#pragma once + +/** \file + * \ingroup bgpencil + */ + +#include "BLI_float2.hh" +#include "BLI_float3.hh" +#include "BLI_float4x4.hh" +#include "BLI_vector.hh" + +#include "DNA_space_types.h" /* for FILE_MAX */ + +#include "gpencil_io.h" + +struct Depsgraph; +struct Main; +struct Object; +struct RegionView3D; +struct Scene; + +struct bGPdata; +struct bGPDlayer; +struct bGPDstroke; + +using blender::Vector; + +namespace blender::io::gpencil { + +class GpencilIO { + public: + GpencilIO(const GpencilIOParams *iparams); + + void frame_number_set(const int value); + + protected: + GpencilIOParams params_; + + bool invert_axis_[2]; + float4x4 diff_mat_; + char filename_[FILE_MAX]; + + /* Used for sorting objects. */ + struct ObjectZ { + float zdepth; + struct Object *ob; + }; + + /** List of included objects. */ + blender::Vector<ObjectZ> ob_list_; + + /* Data for easy access. */ + struct Depsgraph *depsgraph_; + struct bGPdata *gpd_; + struct Main *bmain_; + struct Scene *scene_; + struct RegionView3D *rv3d_; + + int16_t winx_, winy_; + int16_t render_x_, render_y_; + float camera_ratio_; + rctf camera_rect_; + + float2 offset_; + + int cfra_; + + float stroke_color_[4], fill_color_[4]; + + /* Geometry functions. */ + bool gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co); + float2 gpencil_3D_point_to_render_space(const float3 co); + float2 gpencil_3D_point_to_2D(const float3 co); + + float stroke_point_radius_get(struct bGPDlayer *gpl, struct bGPDstroke *gps); + void create_object_list(); + + bool is_camera_mode(); + + float stroke_average_opacity_get(); + + void prepare_layer_export_matrix(struct Object *ob, struct bGPDlayer *gpl); + void prepare_stroke_export_colors(struct Object *ob, struct bGPDstroke *gps); + + void selected_objects_boundbox_calc(); + void selected_objects_boundbox_get(rctf *boundbox); + void filename_set(const char *filename); + + private: + float avg_opacity_; + bool is_camera_; + rctf select_boundbox_; + + /* Camera matrix. */ + float persmat_[4][4]; +}; + +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_capi.cc b/source/blender/io/gpencil/intern/gpencil_io_capi.cc new file mode 100644 index 00000000000..231d23948ef --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_capi.cc @@ -0,0 +1,204 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ + +/** \file + * \ingroup bgpencil + */ + +#include <stdio.h> + +#include "BLI_listbase.h" + +#include "DNA_gpencil_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + +#include "BKE_context.h" +#include "BKE_gpencil.h" +#include "BKE_main.h" +#include "BKE_scene.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "../gpencil_io.h" + +#ifdef WITH_HARU +# include "gpencil_io_export_pdf.h" +#endif + +#ifdef WITH_PUGIXML +# include "gpencil_io_export_svg.h" +#endif + +#include "gpencil_io_import_svg.h" + +#ifdef WITH_HARU +using blender::io::gpencil::GpencilExporterPDF; +#endif +#ifdef WITH_PUGIXML +using blender::io::gpencil::GpencilExporterSVG; +#endif +using blender::io::gpencil::GpencilImporterSVG; + +/* Check if frame is included. */ +#ifdef WITH_HARU +static bool is_keyframe_included(bGPdata *gpd_, const int32_t framenum, const bool use_selected) +{ + /* Check if exist a frame. */ + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_->layers) { + if (gpl->flag & GP_LAYER_HIDE) { + continue; + } + LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { + if (gpf->framenum == framenum) { + if ((!use_selected) || (use_selected && (gpf->flag & GP_FRAME_SELECT))) { + return true; + } + } + } + } + return false; +} +#endif + +/* Import frame. */ +static bool gpencil_io_import_frame(void *in_importer, const GpencilIOParams &iparams) +{ + + bool result = false; + switch (iparams.mode) { + case GP_IMPORT_FROM_SVG: { + GpencilImporterSVG *importer = (GpencilImporterSVG *)in_importer; + result |= importer->read(); + break; + } + /* Add new import formats here. */ + default: + break; + } + + return result; +} + +/* Export frame in PDF. */ +#ifdef WITH_HARU +static bool gpencil_io_export_pdf(Depsgraph *depsgraph, + Scene *scene, + Object *ob, + GpencilExporterPDF *exporter, + const GpencilIOParams *iparams) +{ + bool result = false; + Object *ob_eval_ = (Object *)DEG_get_evaluated_id(depsgraph, &ob->id); + bGPdata *gpd_eval = (bGPdata *)ob_eval_->data; + + exporter->frame_number_set(iparams->frame_cur); + result |= exporter->new_document(); + + const bool use_frame_selected = (iparams->frame_mode == GP_EXPORT_FRAME_SELECTED); + if (use_frame_selected) { + for (int32_t i = iparams->frame_start; i < iparams->frame_end + 1; i++) { + if (!is_keyframe_included(gpd_eval, i, use_frame_selected)) { + continue; + } + + CFRA = i; + BKE_scene_graph_update_for_newframe(depsgraph); + exporter->frame_number_set(i); + exporter->add_newpage(); + exporter->add_body(); + } + result = exporter->write(); + /* Back to original frame. */ + exporter->frame_number_set(iparams->frame_cur); + CFRA = iparams->frame_cur; + BKE_scene_graph_update_for_newframe(depsgraph); + } + else { + exporter->add_newpage(); + exporter->add_body(); + result = exporter->write(); + } + + return result; +} +#endif + +/* Export current frame in SVG. */ +#ifdef WITH_PUGIXML +static bool gpencil_io_export_frame_svg(GpencilExporterSVG *exporter, + const GpencilIOParams *iparams, + const bool newpage, + const bool body, + const bool savepage) +{ + bool result = false; + exporter->frame_number_set(iparams->frame_cur); + if (newpage) { + result |= exporter->add_newpage(); + } + if (body) { + result |= exporter->add_body(); + } + if (savepage) { + result = exporter->write(); + } + return result; +} +#endif + +/* Main import entry point function. */ +bool gpencil_io_import(const char *filename, GpencilIOParams *iparams) +{ + GpencilImporterSVG importer = GpencilImporterSVG(filename, iparams); + + return gpencil_io_import_frame(&importer, *iparams); +} + +/* Main export entry point function. */ +bool gpencil_io_export(const char *filename, GpencilIOParams *iparams) +{ + Depsgraph *depsgraph_ = CTX_data_depsgraph_pointer(iparams->C); + Scene *scene_ = CTX_data_scene(iparams->C); + Object *ob = CTX_data_active_object(iparams->C); + + UNUSED_VARS(filename, depsgraph_, scene_, ob); + + switch (iparams->mode) { +#ifdef WITH_PUGIXML + case GP_EXPORT_TO_SVG: { + GpencilExporterSVG exporter = GpencilExporterSVG(filename, iparams); + return gpencil_io_export_frame_svg(&exporter, iparams, true, true, true); + break; + } +#endif +#ifdef WITH_HARU + case GP_EXPORT_TO_PDF: { + GpencilExporterPDF exporter = GpencilExporterPDF(filename, iparams); + return gpencil_io_export_pdf(depsgraph_, scene_, ob, &exporter, iparams); + break; + } +#endif + /* Add new export formats here. */ + default: + break; + } + return false; +} diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_base.h b/source/blender/io/gpencil/intern/gpencil_io_export_base.h new file mode 100644 index 00000000000..19a24a75fd2 --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_export_base.h @@ -0,0 +1,38 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ +#pragma once + +/** \file + * \ingroup bgpencil + */ +#include "gpencil_io_base.h" + +namespace blender::io::gpencil { + +class GpencilExporter : public GpencilIO { + + public: + GpencilExporter(const struct GpencilIOParams *iparams) : GpencilIO(iparams){}; + virtual bool write() = 0; + + protected: + private: +}; + +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc new file mode 100644 index 00000000000..ba16d635c2d --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc @@ -0,0 +1,311 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ + +/** \file + * \ingroup bgpencil + */ + +#include "BLI_math_vector.h" + +#include "DNA_gpencil_types.h" +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_context.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_geom.h" +#include "BKE_main.h" +#include "BKE_material.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "ED_gpencil.h" +#include "ED_view3d.h" + +#ifdef WIN32 +# include "utfconv.h" +#endif + +#include "UI_view2d.h" + +#include "gpencil_io.h" +#include "gpencil_io_export_pdf.h" + +namespace blender ::io ::gpencil { + +static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void *UNUSED(user_data)) +{ + printf("ERROR: error_no=%04X, detail_no=%u\n", (HPDF_UINT)error_no, (HPDF_UINT)detail_no); +} + +/* Constructor. */ +GpencilExporterPDF::GpencilExporterPDF(const char *filename, const GpencilIOParams *iparams) + : GpencilExporter(iparams) +{ + filename_set(filename); + + invert_axis_[0] = false; + invert_axis_[1] = false; + + pdf_ = nullptr; + page_ = nullptr; + gstate_ = nullptr; +} + +bool GpencilExporterPDF::new_document() +{ + return create_document(); +} + +bool GpencilExporterPDF::add_newpage() +{ + return add_page(); +} + +bool GpencilExporterPDF::add_body() +{ + export_gpencil_layers(); + return true; +} + +bool GpencilExporterPDF::write() +{ + /* Support unicode character paths on Windows. */ + HPDF_STATUS res = 0; + /* TODO: It looks libharu does not support unicode. */ + //#ifdef WIN32 + // char filename_cstr[FILE_MAX]; + // BLI_strncpy(filename_cstr, filename_, FILE_MAX); + // + // UTF16_ENCODE(filename_cstr); + // std::wstring wstr(filename_cstr_16); + // res = HPDF_SaveToFile(pdf_, wstr.c_str()); + // + // UTF16_UN_ENCODE(filename_cstr); + //#else + res = HPDF_SaveToFile(pdf_, filename_); + //#endif + + return (res == 0) ? true : false; +} + +/* Create pdf document. */ +bool GpencilExporterPDF::create_document() +{ + pdf_ = HPDF_New(error_handler, nullptr); + if (!pdf_) { + std::cout << "error: cannot create PdfDoc object\n"; + return false; + } + return true; +} + +/* Add page. */ +bool GpencilExporterPDF::add_page() +{ + /* Add a new page object. */ + page_ = HPDF_AddPage(pdf_); + if (!pdf_) { + std::cout << "error: cannot create PdfPage\n"; + return false; + } + + HPDF_Page_SetWidth(page_, render_x_); + HPDF_Page_SetHeight(page_, render_y_); + + return true; +} + +/* Main layer loop. */ +void GpencilExporterPDF::export_gpencil_layers() +{ + /* If is doing a set of frames, the list of objects can change for each frame. */ + create_object_list(); + + const bool is_normalized = ((params_.flag & GP_EXPORT_NORM_THICKNESS) != 0); + + for (ObjectZ &obz : ob_list_) { + Object *ob = obz.ob; + + /* Use evaluated version to get strokes with modifiers. */ + Object *ob_eval_ = (Object *)DEG_get_evaluated_id(depsgraph_, &ob->id); + bGPdata *gpd_eval = (bGPdata *)ob_eval_->data; + + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_eval->layers) { + if (gpl->flag & GP_LAYER_HIDE) { + continue; + } + prepare_layer_export_matrix(ob, gpl); + + bGPDframe *gpf = gpl->actframe; + if ((gpf == nullptr) || (gpf->strokes.first == nullptr)) { + continue; + } + + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + if (gps->totpoints < 2) { + continue; + } + if (!ED_gpencil_stroke_material_visible(ob, gps)) { + continue; + } + /* Duplicate the stroke to apply any layer thickness change. */ + bGPDstroke *gps_duplicate = BKE_gpencil_stroke_duplicate(gps, true, false); + MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, + gps_duplicate->mat_nr + 1); + + const bool is_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) && + (gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH)); + const bool is_fill = ((gp_style->flag & GP_MATERIAL_FILL_SHOW) && + (gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH)); + prepare_stroke_export_colors(ob, gps_duplicate); + + /* Apply layer thickness change. */ + gps_duplicate->thickness += gpl->line_change; + /* Apply object scale to thickness. */ + gps_duplicate->thickness *= mat4_to_scale(ob->obmat); + CLAMP_MIN(gps_duplicate->thickness, 1.0f); + /* Fill. */ + if ((is_fill) && (params_.flag & GP_EXPORT_FILL)) { + /* Fill is exported as polygon for fill and stroke in a different shape. */ + export_stroke_to_polyline(gpl, gps_duplicate, is_stroke, true, false); + } + + /* Stroke. */ + if (is_stroke) { + if (is_normalized) { + export_stroke_to_polyline(gpl, gps_duplicate, is_stroke, false, true); + } + else { + bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view( + rv3d_, gpd_, gpl, gps_duplicate, 3, diff_mat_.values); + + /* Sample stroke. */ + if (params_.stroke_sample > 0.0f) { + BKE_gpencil_stroke_sample(gpd_eval, gps_perimeter, params_.stroke_sample, false); + } + + export_stroke_to_polyline(gpl, gps_perimeter, is_stroke, false, false); + + BKE_gpencil_free_stroke(gps_perimeter); + } + } + BKE_gpencil_free_stroke(gps_duplicate); + } + } + } +} + +/** + * Export a stroke using polyline or polygon + * \param do_fill: True if the stroke is only fill + */ +void GpencilExporterPDF::export_stroke_to_polyline(bGPDlayer *gpl, + bGPDstroke *gps, + const bool is_stroke, + const bool do_fill, + const bool normalize) +{ + const bool cyclic = ((gps->flag & GP_STROKE_CYCLIC) != 0); + const float avg_pressure = BKE_gpencil_stroke_average_pressure_get(gps); + + /* Get the thickness in pixels using a simple 1 point stroke. */ + bGPDstroke *gps_temp = BKE_gpencil_stroke_duplicate(gps, false, false); + gps_temp->totpoints = 1; + gps_temp->points = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint), "gp_stroke_points"); + const bGPDspoint *pt_src = &gps->points[0]; + bGPDspoint *pt_dst = &gps_temp->points[0]; + copy_v3_v3(&pt_dst->x, &pt_src->x); + pt_dst->pressure = avg_pressure; + + const float radius = stroke_point_radius_get(gpl, gps_temp); + + BKE_gpencil_free_stroke(gps_temp); + + color_set(gpl, do_fill); + + if (is_stroke && !do_fill) { + HPDF_Page_SetLineJoin(page_, HPDF_ROUND_JOIN); + HPDF_Page_SetLineWidth(page_, MAX2((radius * 2.0f) - gpl->line_change, 1.0f)); + } + + /* Loop all points. */ + for (const int i : IndexRange(gps->totpoints)) { + bGPDspoint *pt = &gps->points[i]; + const float2 screen_co = gpencil_3D_point_to_2D(&pt->x); + if (i == 0) { + HPDF_Page_MoveTo(page_, screen_co.x, screen_co.y); + } + else { + HPDF_Page_LineTo(page_, screen_co.x, screen_co.y); + } + } + /* Close cyclic */ + if (cyclic) { + HPDF_Page_ClosePath(page_); + } + + if (do_fill || !normalize) { + HPDF_Page_Fill(page_); + } + else { + HPDF_Page_Stroke(page_); + } + + HPDF_Page_GRestore(page_); +} + +/** + * Set color + * @param do_fill: True if the stroke is only fill + */ +void GpencilExporterPDF::color_set(bGPDlayer *gpl, const bool do_fill) +{ + const float fill_opacity = fill_color_[3] * gpl->opacity; + const float stroke_opacity = stroke_color_[3] * stroke_average_opacity_get() * gpl->opacity; + + HPDF_Page_GSave(page_); + gstate_ = HPDF_CreateExtGState(pdf_); + + float col[3]; + if (do_fill) { + interp_v3_v3v3(col, fill_color_, gpl->tintcolor, gpl->tintcolor[3]); + linearrgb_to_srgb_v3_v3(col, col); + CLAMP3(col, 0.0f, 1.0f); + + HPDF_ExtGState_SetAlphaFill(gstate_, clamp_f(fill_opacity, 0.0f, 1.0f)); + HPDF_Page_SetRGBFill(page_, col[0], col[1], col[2]); + } + else { + interp_v3_v3v3(col, stroke_color_, gpl->tintcolor, gpl->tintcolor[3]); + linearrgb_to_srgb_v3_v3(col, col); + CLAMP3(col, 0.0f, 1.0f); + + HPDF_ExtGState_SetAlphaFill(gstate_, clamp_f(stroke_opacity, 0.0f, 1.0f)); + HPDF_ExtGState_SetAlphaStroke(gstate_, clamp_f(stroke_opacity, 0.0f, 1.0f)); + HPDF_Page_SetRGBFill(page_, col[0], col[1], col[2]); + HPDF_Page_SetRGBStroke(page_, col[0], col[1], col[2]); + } + HPDF_Page_SetExtGState(page_, gstate_); +} +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.h b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.h new file mode 100644 index 00000000000..009c05a8b49 --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.h @@ -0,0 +1,67 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ +#pragma once + +/** \file + * \ingroup bgpencil + */ + +#include "gpencil_io_export_base.h" +#include "hpdf.h" + +struct GpencilIOParams; +struct bGPDlayer; +struct bGPDstroke; + +#define PDF_EXPORTER_NAME "PDF Exporter for Grease Pencil" +#define PDF_EXPORTER_VERSION "v1.0" + +namespace blender::io::gpencil { + +class GpencilExporterPDF : public GpencilExporter { + + public: + GpencilExporterPDF(const char *filename, const struct GpencilIOParams *iparams); + bool new_document(); + bool add_newpage(); + bool add_body(); + bool write(); + + protected: + private: + /* PDF document. */ + HPDF_Doc pdf_; + /* PDF page. */ + HPDF_Page page_; + /* State. */ + HPDF_ExtGState gstate_; + + bool create_document(); + bool add_page(); + void export_gpencil_layers(); + + void export_stroke_to_polyline(bGPDlayer *gpl, + bGPDstroke *gps, + const bool is_stroke, + const bool do_fill, + const bool normalize); + void color_set(bGPDlayer *gpl, const bool do_fill); +}; + +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc new file mode 100644 index 00000000000..89584cd242f --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc @@ -0,0 +1,464 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ + +/** \file + * \ingroup bgpencil + */ + +#include "BLI_math_vector.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "DNA_gpencil_types.h" +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" + +#include "BKE_gpencil.h" +#include "BKE_gpencil_geom.h" +#include "BKE_main.h" +#include "BKE_material.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "ED_gpencil.h" +#include "ED_view3d.h" + +#ifdef WIN32 +# include "utfconv.h" +#endif + +#include "UI_view2d.h" + +#include "gpencil_io.h" +#include "gpencil_io_export_svg.h" + +#include "pugixml.hpp" + +namespace blender ::io ::gpencil { + +/* Constructor. */ +GpencilExporterSVG::GpencilExporterSVG(const char *filename, const GpencilIOParams *iparams) + : GpencilExporter(iparams) +{ + filename_set(filename); + + invert_axis_[0] = false; + invert_axis_[1] = true; +} + +bool GpencilExporterSVG::add_newpage() +{ + create_document_header(); + return true; +} + +bool GpencilExporterSVG::add_body() +{ + export_gpencil_layers(); + return true; +} + +bool GpencilExporterSVG::write() +{ + bool result = true; +/* Support unicode character paths on Windows. */ +#ifdef WIN32 + char filename_cstr[FILE_MAX]; + BLI_strncpy(filename_cstr, filename_, FILE_MAX); + + UTF16_ENCODE(filename_cstr); + std::wstring wstr(filename_cstr_16); + result = main_doc_.save_file(wstr.c_str()); + + UTF16_UN_ENCODE(filename_cstr); +#else + result = main_doc_.save_file(filename_); +#endif + + return result; +} + +/* Create document header and main svg node. */ +void GpencilExporterSVG::create_document_header() +{ + /* Add a custom document declaration node. */ + pugi::xml_node decl = main_doc_.prepend_child(pugi::node_declaration); + decl.append_attribute("version") = "1.0"; + decl.append_attribute("encoding") = "UTF-8"; + + pugi::xml_node comment = main_doc_.append_child(pugi::node_comment); + char txt[128]; + sprintf(txt, " Generator: Blender, %s - %s ", SVG_EXPORTER_NAME, SVG_EXPORTER_VERSION); + comment.set_value(txt); + + pugi::xml_node doctype = main_doc_.append_child(pugi::node_doctype); + doctype.set_value( + "svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" " + "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\""); + + main_node_ = main_doc_.append_child("svg"); + main_node_.append_attribute("version").set_value("1.0"); + main_node_.append_attribute("x").set_value("0px"); + main_node_.append_attribute("y").set_value("0px"); + + std::string width; + std::string height; + + width = std::to_string(render_x_); + height = std::to_string(render_y_); + + main_node_.append_attribute("width").set_value((width + "px").c_str()); + main_node_.append_attribute("height").set_value((height + "px").c_str()); + std::string viewbox = "0 0 " + width + " " + height; + main_node_.append_attribute("viewBox").set_value(viewbox.c_str()); +} + +/* Main layer loop. */ +void GpencilExporterSVG::export_gpencil_layers() +{ + const bool is_clipping = is_camera_mode() && (params_.flag & GP_EXPORT_CLIP_CAMERA) != 0; + + /* If is doing a set of frames, the list of objects can change for each frame. */ + create_object_list(); + + for (ObjectZ &obz : ob_list_) { + Object *ob = obz.ob; + + /* Camera clipping. */ + if (is_clipping) { + pugi::xml_node clip_node = main_node_.append_child("clipPath"); + clip_node.append_attribute("id").set_value(("clip-path" + std::to_string(cfra_)).c_str()); + + add_rect(clip_node, 0, 0, render_x_, render_y_, 0.0f, "#000000"); + } + + frame_node_ = main_node_.append_child("g"); + std::string frametxt = "blender_frame_" + std::to_string(cfra_); + frame_node_.append_attribute("id").set_value(frametxt.c_str()); + + /* Clip area. */ + if (is_clipping) { + frame_node_.append_attribute("clip-path") + .set_value(("url(#clip-path" + std::to_string(cfra_) + ")").c_str()); + } + + pugi::xml_node ob_node = frame_node_.append_child("g"); + + char obtxt[96]; + sprintf(obtxt, "blender_object_%s", ob->id.name + 2); + ob_node.append_attribute("id").set_value(obtxt); + + /* Use evaluated version to get strokes with modifiers. */ + Object *ob_eval_ = (Object *)DEG_get_evaluated_id(depsgraph_, &ob->id); + bGPdata *gpd_eval = (bGPdata *)ob_eval_->data; + + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_eval->layers) { + if (gpl->flag & GP_LAYER_HIDE) { + continue; + } + prepare_layer_export_matrix(ob, gpl); + + bGPDframe *gpf = gpl->actframe; + if ((gpf == nullptr) || (gpf->strokes.first == nullptr)) { + continue; + } + + /* Layer node. */ + std::string txt = "Layer: "; + txt.append(gpl->info); + ob_node.append_child(pugi::node_comment).set_value(txt.c_str()); + + pugi::xml_node node_gpl = ob_node.append_child("g"); + node_gpl.append_attribute("id").set_value(gpl->info); + + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + if (gps->totpoints < 2) { + continue; + } + if (!ED_gpencil_stroke_material_visible(ob, gps)) { + continue; + } + + /* Duplicate the stroke to apply any layer thickness change. */ + bGPDstroke *gps_duplicate = BKE_gpencil_stroke_duplicate(gps, true, false); + + MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, + gps_duplicate->mat_nr + 1); + + const bool is_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) && + (gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH)); + const bool is_fill = ((gp_style->flag & GP_MATERIAL_FILL_SHOW) && + (gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH)); + + prepare_stroke_export_colors(ob, gps_duplicate); + + /* Apply layer thickness change. */ + gps_duplicate->thickness += gpl->line_change; + /* Apply object scale to thickness. */ + gps_duplicate->thickness *= mat4_to_scale(ob->obmat); + CLAMP_MIN(gps_duplicate->thickness, 1.0f); + + const bool is_normalized = ((params_.flag & GP_EXPORT_NORM_THICKNESS) != 0) || + BKE_gpencil_stroke_is_pressure_constant(gps); + + /* Fill. */ + if ((is_fill) && (params_.flag & GP_EXPORT_FILL)) { + /* Fill is always exported as polygon because the stroke of the fill is done + * in a different SVG command. */ + export_stroke_to_polyline(gpl, gps_duplicate, node_gpl, is_stroke, true); + } + + /* Stroke. */ + if (is_stroke) { + if (is_normalized) { + export_stroke_to_polyline(gpl, gps_duplicate, node_gpl, is_stroke, false); + } + else { + bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view( + rv3d_, gpd_, gpl, gps_duplicate, 3, diff_mat_.values); + + /* Sample stroke. */ + if (params_.stroke_sample > 0.0f) { + BKE_gpencil_stroke_sample(gpd_eval, gps_perimeter, params_.stroke_sample, false); + } + + export_stroke_to_path(gpl, gps_perimeter, node_gpl, false); + + BKE_gpencil_free_stroke(gps_perimeter); + } + } + + BKE_gpencil_free_stroke(gps_duplicate); + } + } + } +} + +/** + * Export a stroke using SVG path + * \param node_gpl: Node of the layer. + * \param do_fill: True if the stroke is only fill + */ +void GpencilExporterSVG::export_stroke_to_path(bGPDlayer *gpl, + bGPDstroke *gps, + pugi::xml_node node_gpl, + const bool do_fill) +{ + pugi::xml_node node_gps = node_gpl.append_child("path"); + + float col[3]; + std::string stroke_hex; + if (do_fill) { + node_gps.append_attribute("fill-opacity").set_value(fill_color_[3] * gpl->opacity); + + interp_v3_v3v3(col, fill_color_, gpl->tintcolor, gpl->tintcolor[3]); + } + else { + node_gps.append_attribute("fill-opacity") + .set_value(stroke_color_[3] * stroke_average_opacity_get() * gpl->opacity); + + interp_v3_v3v3(col, stroke_color_, gpl->tintcolor, gpl->tintcolor[3]); + } + + linearrgb_to_srgb_v3_v3(col, col); + stroke_hex = rgb_to_hexstr(col); + + node_gps.append_attribute("fill").set_value(stroke_hex.c_str()); + node_gps.append_attribute("stroke").set_value("none"); + + std::string txt = "M"; + for (const int i : IndexRange(gps->totpoints)) { + if (i > 0) { + txt.append("L"); + } + bGPDspoint &pt = gps->points[i]; + const float2 screen_co = gpencil_3D_point_to_2D(&pt.x); + txt.append(std::to_string(screen_co.x) + "," + std::to_string(screen_co.y)); + } + /* Close patch (cyclic)*/ + if (gps->flag & GP_STROKE_CYCLIC) { + txt.append("z"); + } + + node_gps.append_attribute("d").set_value(txt.c_str()); +} + +/** + * Export a stroke using polyline or polygon + * \param node_gpl: Node of the layer. + * \param do_fill: True if the stroke is only fill + */ +void GpencilExporterSVG::export_stroke_to_polyline(bGPDlayer *gpl, + bGPDstroke *gps, + pugi::xml_node node_gpl, + const bool is_stroke, + const bool do_fill) +{ + const bool cyclic = ((gps->flag & GP_STROKE_CYCLIC) != 0); + const float avg_pressure = BKE_gpencil_stroke_average_pressure_get(gps); + + /* Get the thickness in pixels using a simple 1 point stroke. */ + bGPDstroke *gps_temp = BKE_gpencil_stroke_duplicate(gps, false, false); + gps_temp->totpoints = 1; + gps_temp->points = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint), "gp_stroke_points"); + bGPDspoint *pt_src = &gps->points[0]; + bGPDspoint *pt_dst = &gps_temp->points[0]; + copy_v3_v3(&pt_dst->x, &pt_src->x); + pt_dst->pressure = avg_pressure; + + const float radius = stroke_point_radius_get(gpl, gps_temp); + + BKE_gpencil_free_stroke(gps_temp); + + pugi::xml_node node_gps = node_gpl.append_child(do_fill || cyclic ? "polygon" : "polyline"); + + color_string_set(gpl, gps, node_gps, do_fill); + + if (is_stroke && !do_fill) { + node_gps.append_attribute("stroke-width").set_value((radius * 2.0f) - gpl->line_change); + } + + std::string txt; + for (const int i : IndexRange(gps->totpoints)) { + if (i > 0) { + txt.append(" "); + } + bGPDspoint *pt = &gps->points[i]; + const float2 screen_co = gpencil_3D_point_to_2D(&pt->x); + txt.append(std::to_string(screen_co.x) + "," + std::to_string(screen_co.y)); + } + + node_gps.append_attribute("points").set_value(txt.c_str()); +} + +/** + * Set color SVG string for stroke + * \param node_gps: Stroke node + * @param do_fill: True if the stroke is only fill + */ +void GpencilExporterSVG::color_string_set(bGPDlayer *gpl, + bGPDstroke *gps, + pugi::xml_node node_gps, + const bool do_fill) +{ + const bool round_cap = (gps->caps[0] == GP_STROKE_CAP_ROUND || + gps->caps[1] == GP_STROKE_CAP_ROUND); + + float col[3]; + if (do_fill) { + interp_v3_v3v3(col, fill_color_, gpl->tintcolor, gpl->tintcolor[3]); + linearrgb_to_srgb_v3_v3(col, col); + std::string stroke_hex = rgb_to_hexstr(col); + node_gps.append_attribute("fill").set_value(stroke_hex.c_str()); + node_gps.append_attribute("stroke").set_value("none"); + node_gps.append_attribute("fill-opacity").set_value(fill_color_[3] * gpl->opacity); + } + else { + interp_v3_v3v3(col, stroke_color_, gpl->tintcolor, gpl->tintcolor[3]); + linearrgb_to_srgb_v3_v3(col, col); + std::string stroke_hex = rgb_to_hexstr(col); + node_gps.append_attribute("stroke").set_value(stroke_hex.c_str()); + node_gps.append_attribute("stroke-opacity") + .set_value(stroke_color_[3] * stroke_average_opacity_get() * gpl->opacity); + + if (gps->totpoints > 1) { + node_gps.append_attribute("fill").set_value("none"); + node_gps.append_attribute("stroke-linecap").set_value(round_cap ? "round" : "square"); + } + else { + node_gps.append_attribute("fill").set_value(stroke_hex.c_str()); + node_gps.append_attribute("fill-opacity").set_value(fill_color_[3] * gpl->opacity); + } + } +} + +/** + * Create a SVG rectangle + * \param node: Parent node + * \param x: X location + * \param y: Y location + * \param width: width of the recntagle + * \param height: Height of the rectangle + * \param thickness: Thickness of the line + * \param hexcolor: Color of the line + */ +void GpencilExporterSVG::add_rect(pugi::xml_node node, + float x, + float y, + float width, + float height, + float thickness, + std::string hexcolor) +{ + pugi::xml_node rect_node = node.append_child("rect"); + rect_node.append_attribute("x").set_value(x); + rect_node.append_attribute("y").set_value(y); + rect_node.append_attribute("width").set_value(width); + rect_node.append_attribute("height").set_value(height); + rect_node.append_attribute("fill").set_value("none"); + if (thickness > 0.0f) { + rect_node.append_attribute("stroke").set_value(hexcolor.c_str()); + rect_node.append_attribute("stroke-width").set_value(thickness); + } +} + +/** + * Create SVG text + * \param node: Parent node + * \param x: X location + * \param y: Y location + * \param text: Text to include + * \param size: Size of th etext + * \param hexcolor: Color of the text + */ +void GpencilExporterSVG::add_text(pugi::xml_node node, + float x, + float y, + std::string text, + const float size, + std::string hexcolor) +{ + pugi::xml_node nodetxt = node.append_child("text"); + + nodetxt.append_attribute("x").set_value(x); + nodetxt.append_attribute("y").set_value(y); + // nodetxt.append_attribute("font-family").set_value("'system-ui'"); + nodetxt.append_attribute("font-size").set_value(size); + nodetxt.append_attribute("fill").set_value(hexcolor.c_str()); + nodetxt.text().set(text.c_str()); +} + +/** Convert a color to Hex value (#FFFFFF). */ +std::string GpencilExporterSVG::rgb_to_hexstr(float color[3]) +{ + uint8_t r = color[0] * 255.0f; + uint8_t g = color[1] * 255.0f; + uint8_t b = color[2] * 255.0f; + char hex_string[20]; + sprintf(hex_string, "#%02X%02X%02X", r, g, b); + + std::string hexstr = hex_string; + + return hexstr; +} + +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.h b/source/blender/io/gpencil/intern/gpencil_io_export_svg.h new file mode 100644 index 00000000000..f564736c16e --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.h @@ -0,0 +1,89 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ +#pragma once + +/** \file + * \ingroup bgpencil + */ +#include "BLI_path_util.h" + +#include "gpencil_io_export_base.h" +#include "pugixml.hpp" + +struct GpencilIOParams; + +#define SVG_EXPORTER_NAME "SVG Export for Grease Pencil" +#define SVG_EXPORTER_VERSION "v1.0" + +namespace blender::io::gpencil { + +class GpencilExporterSVG : public GpencilExporter { + + public: + GpencilExporterSVG(const char *filename, const struct GpencilIOParams *iparams); + bool add_newpage(); + bool add_body(); + bool write(); + + protected: + static void add_rect(pugi::xml_node node, + float x, + float y, + float width, + float height, + float thickness, + std::string hexcolor); + + static void add_text(pugi::xml_node node, + float x, + float y, + std::string text, + const float size, + std::string hexcolor); + + private: + /* XML doc. */ + pugi::xml_document main_doc_; + /* Main document node. */ + pugi::xml_node main_node_; + /** Frame node */ + pugi::xml_node frame_node_; + void create_document_header(); + void export_gpencil_layers(); + + void export_stroke_to_path(struct bGPDlayer *gpl, + struct bGPDstroke *gps, + pugi::xml_node node_gpl, + const bool is_fill); + + void export_stroke_to_polyline(struct bGPDlayer *gpl, + struct bGPDstroke *gps, + pugi::xml_node node_gpl, + const bool is_stroke, + const bool is_fill); + + void color_string_set(struct bGPDlayer *gpl, + struct bGPDstroke *gps, + pugi::xml_node node_gps, + const bool is_fill); + + std::string rgb_to_hexstr(float color[3]); +}; + +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_base.cc b/source/blender/io/gpencil/intern/gpencil_io_import_base.cc new file mode 100644 index 00000000000..2e7cfdeb5cd --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_import_base.cc @@ -0,0 +1,83 @@ + + +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ + +/** \file + * \ingroup bgpencil + */ +#include "BLI_math_vector.h" + +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_gpencil.h" +#include "BKE_material.h" + +#include "ED_gpencil.h" + +#include "gpencil_io_import_base.h" + +namespace blender::io::gpencil { + +/* Constructor. */ +GpencilImporter::GpencilImporter(const GpencilIOParams *iparams) : GpencilIO(iparams) +{ + /* Nothing to do yet */ +} + +Object *GpencilImporter::create_object() +{ + const float *cur = scene_->cursor.location; + ushort local_view_bits = (params_.v3d && params_.v3d->localvd) ? params_.v3d->local_view_uuid : + (ushort)0; + Object *ob_gpencil = ED_gpencil_add_object(params_.C, cur, local_view_bits); + + return ob_gpencil; +} + +int32_t GpencilImporter::create_material(const char *name, const bool stroke, const bool fill) +{ + const float default_stroke_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + const float default_fill_color[4] = {0.5f, 0.5f, 0.5f, 1.0f}; + int32_t mat_index = BKE_gpencil_material_find_index_by_name_prefix(params_.ob, name); + /* Stroke and Fill material. */ + if (mat_index == -1) { + int32_t new_idx; + Material *mat_gp = BKE_gpencil_object_material_new(bmain_, params_.ob, name, &new_idx); + MaterialGPencilStyle *gp_style = mat_gp->gp_style; + gp_style->flag &= ~GP_MATERIAL_STROKE_SHOW; + gp_style->flag &= ~GP_MATERIAL_FILL_SHOW; + + copy_v4_v4(gp_style->stroke_rgba, default_stroke_color); + copy_v4_v4(gp_style->fill_rgba, default_fill_color); + if (stroke) { + gp_style->flag |= GP_MATERIAL_STROKE_SHOW; + } + if (fill) { + gp_style->flag |= GP_MATERIAL_FILL_SHOW; + } + mat_index = params_.ob->totcol - 1; + } + + return mat_index; +} + +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_base.h b/source/blender/io/gpencil/intern/gpencil_io_import_base.h new file mode 100644 index 00000000000..efe6264e4e9 --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_import_base.h @@ -0,0 +1,41 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ +#pragma once + +/** \file + * \ingroup bgpencil + */ +#include "gpencil_io_base.h" + +namespace blender::io::gpencil { + +class GpencilImporter : public GpencilIO { + + public: + GpencilImporter(const struct GpencilIOParams *iparams); + virtual bool read() = 0; + + protected: + struct Object *create_object(); + int32_t create_material(const char *name, const bool stroke, const bool fill); + + private: +}; + +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc new file mode 100644 index 00000000000..7f450477ac2 --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc @@ -0,0 +1,253 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ + +/** \file + * \ingroup bgpencil + */ + +#include "BLI_float3.hh" +#include "BLI_math.h" +#include "BLI_span.hh" + +#include "DNA_gpencil_types.h" + +#include "BKE_gpencil.h" +#include "BKE_gpencil_geom.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "ED_gpencil.h" + +#include "gpencil_io.h" +#include "gpencil_io_import_svg.h" + +/* Custom flags for NanoSVG. */ +#define NANOSVG_ALL_COLOR_KEYWORDS +#define NANOSVG_IMPLEMENTATION + +#include "nanosvg/nanosvg.h" + +using blender::MutableSpan; + +namespace blender::io::gpencil { + +/* Constructor. */ +GpencilImporterSVG::GpencilImporterSVG(const char *filename, const GpencilIOParams *iparams) + : GpencilImporter(iparams) +{ + filename_set(filename); +} + +bool GpencilImporterSVG::read() +{ + bool result = true; + NSVGimage *svg_data = nullptr; + svg_data = nsvgParseFromFile(filename_, "mm", 96.0f); + if (svg_data == nullptr) { + std::cout << " Could not open SVG.\n "; + return false; + } + + /* Create grease pencil object. */ + params_.ob = create_object(); + if (params_.ob == nullptr) { + std::cout << "Unable to create new object.\n"; + if (svg_data) { + nsvgDelete(svg_data); + } + + return false; + } + gpd_ = (bGPdata *)params_.ob->data; + + /* Grease pencil is rotated 90 degrees in X axis by default. */ + float matrix[4][4]; + const float3 scale = float3(params_.scale); + unit_m4(matrix); + rotate_m4(matrix, 'X', DEG2RADF(-90.0f)); + rescale_m4(matrix, scale); + + /* Loop all shapes. */ + char prv_id[70] = {"*"}; + int prefix = 0; + for (NSVGshape *shape = svg_data->shapes; shape; shape = shape->next) { + char *layer_id = (shape->id_parent[0] == '\0') ? BLI_sprintfN("Layer_%03d", prefix) : + BLI_sprintfN("%s", shape->id_parent); + if (!STREQ(prv_id, layer_id)) { + prefix++; + MEM_freeN(layer_id); + layer_id = (shape->id_parent[0] == '\0') ? BLI_sprintfN("Layer_%03d", prefix) : + BLI_sprintfN("%s", shape->id_parent); + strcpy(prv_id, layer_id); + } + + /* Check if the layer exist and create if needed. */ + bGPDlayer *gpl = (bGPDlayer *)BLI_findstring( + &gpd_->layers, layer_id, offsetof(bGPDlayer, info)); + if (gpl == nullptr) { + gpl = BKE_gpencil_layer_addnew(gpd_, layer_id, true); + /* Disable lights. */ + gpl->flag &= ~GP_LAYER_USE_LIGHTS; + } + MEM_freeN(layer_id); + + /* Check frame. */ + bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, cfra_, GP_GETFRAME_ADD_NEW); + /* Create materials. */ + bool is_stroke = (bool)shape->stroke.type; + bool is_fill = (bool)shape->fill.type; + if ((!is_stroke) && (!is_fill)) { + is_stroke = true; + } + + /* Create_shape materials. */ + const char *const mat_names[] = {"Stroke", "Fill"}; + int index = 0; + if ((is_stroke) && (is_fill)) { + index = 0; + is_fill = false; + } + else if ((!is_stroke) && (is_fill)) { + index = 1; + } + int32_t mat_index = create_material(mat_names[index], is_stroke, is_fill); + + /* Loop all paths to create the stroke data. */ + for (NSVGpath *path = shape->paths; path; path = path->next) { + create_stroke(gpd_, gpf, shape, path, mat_index, matrix); + } + } + + /* Free SVG memory. */ + nsvgDelete(svg_data); + + /* Calculate bounding box and move all points to new origin center. */ + float gp_center[3]; + BKE_gpencil_centroid_3d(gpd_, gp_center); + + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_->layers) { + LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + for (bGPDspoint &pt : MutableSpan(gps->points, gps->totpoints)) { + sub_v3_v3(&pt.x, gp_center); + } + } + } + } + + return result; +} + +void GpencilImporterSVG::create_stroke(bGPdata *gpd, + bGPDframe *gpf, + NSVGshape *shape, + NSVGpath *path, + const int32_t mat_index, + const float matrix[4][4]) +{ + const bool is_stroke = (bool)shape->stroke.type; + const bool is_fill = (bool)shape->fill.type; + + const int edges = params_.resolution; + const float step = 1.0f / (float)(edges - 1); + + const int totpoints = (path->npts / 3) * params_.resolution; + + bGPDstroke *gps = BKE_gpencil_stroke_new(mat_index, totpoints, 1.0f); + BLI_addtail(&gpf->strokes, gps); + + if (path->closed == '1') { + gps->flag |= GP_STROKE_CYCLIC; + } + if (is_stroke) { + gps->thickness = shape->strokeWidth * params_.scale; + } + /* Apply Fill vertex color. */ + if (is_fill) { + NSVGpaint fill = shape->fill; + convert_color(fill.color, gps->vert_color_fill); + gps->fill_opacity_fac = gps->vert_color_fill[3]; + gps->vert_color_fill[3] = 1.0f; + } + + int start_index = 0; + for (int i = 0; i < path->npts - 1; i += 3) { + float *p = &path->pts[i * 2]; + float a = 0.0f; + for (int v = 0; v < edges; v++) { + bGPDspoint *pt = &gps->points[start_index]; + pt->strength = shape->opacity; + pt->pressure = 1.0f; + pt->z = 0.0f; + /* TODO: (antoniov) Can be improved loading curve data instead of loading strokes. */ + interp_v2_v2v2v2v2_cubic(&pt->x, &p[0], &p[2], &p[4], &p[6], a); + + /* Scale from milimeters. */ + mul_v3_fl(&pt->x, 0.001f); + mul_m4_v3(matrix, &pt->x); + + /* Apply color to vertex color. */ + if (is_fill) { + NSVGpaint fill = shape->fill; + convert_color(fill.color, pt->vert_color); + } + if (is_stroke) { + NSVGpaint stroke = shape->stroke; + convert_color(stroke.color, pt->vert_color); + gps->fill_opacity_fac = pt->vert_color[3]; + } + pt->vert_color[3] = 1.0f; + + a += step; + start_index++; + } + } + + /* Cleanup and recalculate geometry. */ + BKE_gpencil_stroke_merge_distance(gpd, gpf, gps, 0.001f, true); + BKE_gpencil_stroke_geometry_update(gpd, gps); +} + +/* Unpack internal NanoSVG color. */ +static void unpack_nano_color(const unsigned int pack, float r_col[4]) +{ + unsigned char rgb_u[4]; + + rgb_u[0] = ((pack) >> 0) & 0xFF; + rgb_u[1] = ((pack) >> 8) & 0xFF; + rgb_u[2] = ((pack) >> 16) & 0xFF; + rgb_u[3] = ((pack) >> 24) & 0xFF; + + r_col[0] = (float)rgb_u[0] / 255.0f; + r_col[1] = (float)rgb_u[1] / 255.0f; + r_col[2] = (float)rgb_u[2] / 255.0f; + r_col[3] = (float)rgb_u[3] / 255.0f; +} + +void GpencilImporterSVG::convert_color(const int32_t color, float r_linear_rgba[4]) +{ + float rgba[4]; + unpack_nano_color(color, rgba); + + srgb_to_linearrgb_v3_v3(r_linear_rgba, rgba); + r_linear_rgba[3] = rgba[3]; +} + +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.h b/source/blender/io/gpencil/intern/gpencil_io_import_svg.h new file mode 100644 index 00000000000..6a34ec8423b --- /dev/null +++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.h @@ -0,0 +1,56 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ +#pragma once + +/** \file + * \ingroup bgpencil + */ +#include "gpencil_io_import_base.h" + +struct GpencilIOParams; +struct NSVGshape; +struct NSVGpath; +struct bGPdata; +struct bGPDframe; + +#define SVG_IMPORTER_NAME "SVG Import for Grease Pencil" +#define SVG_IMPORTER_VERSION "v1.0" + +namespace blender::io::gpencil { + +class GpencilImporterSVG : public GpencilImporter { + + public: + GpencilImporterSVG(const char *filename, const struct GpencilIOParams *iparams); + + bool read(); + + protected: + private: + void create_stroke(struct bGPdata *gpd_, + struct bGPDframe *gpf, + struct NSVGshape *shape, + struct NSVGpath *path, + const int32_t mat_index, + const float matrix[4][4]); + + void convert_color(const int32_t color, float r_linear_rgba[4]); +}; + +} // namespace blender::io::gpencil diff --git a/source/blender/io/gpencil/nanosvg/nanosvg.h b/source/blender/io/gpencil/nanosvg/nanosvg.h new file mode 100644 index 00000000000..1009d684f7c --- /dev/null +++ b/source/blender/io/gpencil/nanosvg/nanosvg.h @@ -0,0 +1,3313 @@ +/* + * Copyright (c) 2013-14 Mikko Mononen memon@inside.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * The SVG parser is based on Anti-Grain Geometry 2.4 SVG example + * Copyright (C) 2002-2004 Maxim Shemanarev (McSeem) (http://www.antigrain.com/) + * + * Arc calculation code based on canvg (https://code.google.com/p/canvg/) + * + * Bounding box calculation based on + * http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html + * + * This is a modified version for Blender used by importers. + * + */ + +#ifndef NANOSVG_H +#define NANOSVG_H + +#ifndef NANOSVG_CPLUSPLUS +# ifdef __cplusplus +extern "C" { +# endif +#endif + +// NanoSVG is a simple stupid single-header-file SVG parse. The output of the parser is a list of +// cubic bezier shapes. +// +// The library suits well for anything from rendering scalable icons in your editor application to +// prototyping a game. +// +// NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create +// a pull request! +// +// The shapes in the SVG images are transformed by the viewBox and converted to specified units. +// That is, you should get the same looking data as your designed in your favorite app. +// +// NanoSVG can return the paths in few different units. For example if you want to render an image, +// you may choose to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you +// may want to use millimeters. +// +// The units passed to NanoSVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or 'in'. +// DPI (dots-per-inch) controls how the unit conversion is done. +// +// If you don't know or care about the units stuff, "px" and 96 should get you going. + +/* Example Usage: + // Load SVG + NSVGimage* image; + image = nsvgParseFromFile("test.svg", "px", 96); + printf("size: %f x %f\n", image->width, image->height); + // Use... + for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) { + for (NSVGpath *path = shape->paths; path != NULL; path = path->next) { + for (int i = 0; i < path->npts-1; i += 3) { + float* p = &path->pts[i*2]; + drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]); + } + } + } + // Delete + nsvgDelete(image); +*/ + +enum NSVGpaintType { + NSVG_PAINT_NONE = 0, + NSVG_PAINT_COLOR = 1, + NSVG_PAINT_LINEAR_GRADIENT = 2, + NSVG_PAINT_RADIAL_GRADIENT = 3 +}; + +enum NSVGspreadType { NSVG_SPREAD_PAD = 0, NSVG_SPREAD_REFLECT = 1, NSVG_SPREAD_REPEAT = 2 }; + +enum NSVGlineJoin { NSVG_JOIN_MITER = 0, NSVG_JOIN_ROUND = 1, NSVG_JOIN_BEVEL = 2 }; + +enum NSVGlineCap { NSVG_CAP_BUTT = 0, NSVG_CAP_ROUND = 1, NSVG_CAP_SQUARE = 2 }; + +enum NSVGfillRule { NSVG_FILLRULE_NONZERO = 0, NSVG_FILLRULE_EVENODD = 1 }; + +enum NSVGflags { NSVG_FLAGS_VISIBLE = 0x01 }; + +typedef struct NSVGgradientStop { + unsigned int color; + float offset; +} NSVGgradientStop; + +typedef struct NSVGgradient { + float xform[6]; + char spread; + float fx, fy; + int nstops; + NSVGgradientStop stops[1]; +} NSVGgradient; + +typedef struct NSVGpaint { + char type; + union { + unsigned int color; + NSVGgradient *gradient; + }; +} NSVGpaint; + +typedef struct NSVGpath { + float *pts; // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ... + int npts; // Total number of bezier points. + char closed; // Flag indicating if shapes should be treated as closed. + float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. + struct NSVGpath *next; // Pointer to next path, or NULL if last element. +} NSVGpath; + +typedef struct NSVGshape { + char id[64]; // Optional 'id' attr of the shape or its group + /* Blender: Parent ID used for layer creation. */ + char id_parent[64]; + NSVGpaint fill; // Fill paint + NSVGpaint stroke; // Stroke paint + float opacity; // Opacity of the shape. + float strokeWidth; // Stroke width (scaled). + float strokeDashOffset; // Stroke dash offset (scaled). + float strokeDashArray[8]; // Stroke dash array (scaled). + char strokeDashCount; // Number of dash values in dash array. + char strokeLineJoin; // Stroke join type. + char strokeLineCap; // Stroke cap type. + float miterLimit; // Miter limit + char fillRule; // Fill rule, see NSVGfillRule. + unsigned char flags; // Logical or of NSVG_FLAGS_* flags + float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. + NSVGpath *paths; // Linked list of paths in the image. + struct NSVGshape *next; // Pointer to next shape, or NULL if last element. +} NSVGshape; + +typedef struct NSVGimage { + float width; // Width of the image. + float height; // Height of the image. + NSVGshape *shapes; // Linked list of shapes in the image. +} NSVGimage; + +// Parses SVG file from a file, returns SVG image as paths. +NSVGimage *nsvgParseFromFile(const char *filename, const char *units, float dpi); + +// Parses SVG file from a null terminated string, returns SVG image as paths. +// Important note: changes the string. +NSVGimage *nsvgParse(char *input, const char *units, float dpi); + +// Duplicates a path. +NSVGpath *nsvgDuplicatePath(NSVGpath *p); + +// Deletes an image. +void nsvgDelete(NSVGimage *image); + +#ifndef NANOSVG_CPLUSPLUS +# ifdef __cplusplus +} +# endif +#endif + +#endif // NANOSVG_H + +#ifdef NANOSVG_IMPLEMENTATION + +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#define NSVG_PI (3.14159265358979323846264338327f) +#define NSVG_KAPPA90 \ + (0.5522847493f) // Length proportional to radius of a cubic bezier handle for 90deg arcs. + +#define NSVG_ALIGN_MIN 0 +#define NSVG_ALIGN_MID 1 +#define NSVG_ALIGN_MAX 2 +#define NSVG_ALIGN_NONE 0 +#define NSVG_ALIGN_MEET 1 +#define NSVG_ALIGN_SLICE 2 + +#define NSVG_NOTUSED(v) \ + do { \ + (void)(1 ? (void)0 : ((void)(v))); \ + } while (0) +#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16)) + +#ifdef _MSC_VER +# pragma warning(disable : 4996) // Switch off security warnings +# pragma warning(disable : 4100) // Switch off unreferenced formal parameter warnings +# ifdef __cplusplus +# define NSVG_INLINE inline +# else +# define NSVG_INLINE +# endif +#else +# define NSVG_INLINE inline +#endif + +static int nsvg__isspace(char c) +{ + return strchr(" \t\n\v\f\r", c) != 0; +} + +static int nsvg__isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static NSVG_INLINE float nsvg__minf(float a, float b) +{ + return a < b ? a : b; +} +static NSVG_INLINE float nsvg__maxf(float a, float b) +{ + return a > b ? a : b; +} + +// Simple XML parser + +#define NSVG_XML_TAG 1 +#define NSVG_XML_CONTENT 2 +#define NSVG_XML_MAX_ATTRIBS 256 + +static void nsvg__parseContent(char *s, void (*contentCb)(void *ud, const char *s), void *ud) +{ + // Trim start white spaces + while (*s && nsvg__isspace(*s)) + s++; + if (!*s) + return; + + if (contentCb) + (*contentCb)(ud, s); +} + +static void nsvg__parseElement(char *s, + void (*startelCb)(void *ud, const char *el, const char **attr), + void (*endelCb)(void *ud, const char *el), + void *ud) +{ + const char *attr[NSVG_XML_MAX_ATTRIBS]; + int nattr = 0; + char *name; + int start = 0; + int end = 0; + char quote; + + // Skip white space after the '<' + while (*s && nsvg__isspace(*s)) + s++; + + // Check if the tag is end tag + if (*s == '/') { + s++; + end = 1; + } + else { + start = 1; + } + + // Skip comments, data and preprocessor stuff. + if (!*s || *s == '?' || *s == '!') + return; + + // Get tag name + name = s; + while (*s && !nsvg__isspace(*s)) + s++; + if (*s) { + *s++ = '\0'; + } + + // Get attribs + while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS - 3) { + char *name = NULL; + char *value = NULL; + + // Skip white space before the attrib name + while (*s && nsvg__isspace(*s)) + s++; + if (!*s) + break; + if (*s == '/') { + end = 1; + break; + } + name = s; + // Find end of the attrib name. + while (*s && !nsvg__isspace(*s) && *s != '=') + s++; + if (*s) { + *s++ = '\0'; + } + // Skip until the beginning of the value. + while (*s && *s != '\"' && *s != '\'') + s++; + if (!*s) + break; + quote = *s; + s++; + // Store value and find the end of it. + value = s; + while (*s && *s != quote) + s++; + if (*s) { + *s++ = '\0'; + } + + // Store only well formed attributes + if (name && value) { + attr[nattr++] = name; + attr[nattr++] = value; + } + } + + // List terminator + attr[nattr++] = 0; + attr[nattr++] = 0; + + // Call callbacks. + if (start && startelCb) + (*startelCb)(ud, name, attr); + if (end && endelCb) + (*endelCb)(ud, name); +} + +static int nsvg__parseXML(char *input, + void (*startelCb)(void *ud, const char *el, const char **attr), + void (*endelCb)(void *ud, const char *el), + void (*contentCb)(void *ud, const char *s), + void *ud) +{ + char *s = input; + char *mark = s; + int state = NSVG_XML_CONTENT; + while (*s) { + if (*s == '<' && state == NSVG_XML_CONTENT) { + // Start of a tag + *s++ = '\0'; + nsvg__parseContent(mark, contentCb, ud); + mark = s; + state = NSVG_XML_TAG; + } + else if (*s == '>' && state == NSVG_XML_TAG) { + // Start of a content or new tag. + *s++ = '\0'; + nsvg__parseElement(mark, startelCb, endelCb, ud); + mark = s; + state = NSVG_XML_CONTENT; + } + else { + s++; + } + } + + return 1; +} + +/* Simple SVG parser. */ + +#define NSVG_MAX_ATTR 128 +#define NSVG_MAX_BREADCRUMB 5 + +enum NSVGgradientUnits { NSVG_USER_SPACE = 0, NSVG_OBJECT_SPACE = 1 }; + +#define NSVG_MAX_DASHES 8 + +enum NSVGunits { + NSVG_UNITS_USER, + NSVG_UNITS_PX, + NSVG_UNITS_PT, + NSVG_UNITS_PC, + NSVG_UNITS_MM, + NSVG_UNITS_CM, + NSVG_UNITS_IN, + NSVG_UNITS_PERCENT, + NSVG_UNITS_EM, + NSVG_UNITS_EX +}; + +typedef struct NSVGcoordinate { + float value; + int units; +} NSVGcoordinate; + +typedef struct NSVGlinearData { + NSVGcoordinate x1, y1, x2, y2; +} NSVGlinearData; + +typedef struct NSVGradialData { + NSVGcoordinate cx, cy, r, fx, fy; +} NSVGradialData; + +typedef struct NSVGgradientData { + char id[64]; + char ref[64]; + char type; + union { + NSVGlinearData linear; + NSVGradialData radial; + }; + char spread; + char units; + float xform[6]; + int nstops; + NSVGgradientStop *stops; + struct NSVGgradientData *next; +} NSVGgradientData; + +typedef struct NSVGattrib { + char id[64]; + float xform[6]; + unsigned int fillColor; + unsigned int strokeColor; + float opacity; + float fillOpacity; + float strokeOpacity; + char fillGradient[64]; + char strokeGradient[64]; + float strokeWidth; + float strokeDashOffset; + float strokeDashArray[NSVG_MAX_DASHES]; + int strokeDashCount; + char strokeLineJoin; + char strokeLineCap; + float miterLimit; + char fillRule; + float fontSize; + unsigned int stopColor; + float stopOpacity; + float stopOffset; + char hasFill; + char hasStroke; + char visible; +} NSVGattrib; + +typedef struct NSVGparser { + NSVGattrib attr[NSVG_MAX_ATTR]; + int attrHead; + float *pts; + int npts; + int cpts; + NSVGpath *plist; + NSVGimage *image; + NSVGgradientData *gradients; + NSVGshape *shapesTail; + float viewMinx, viewMiny, viewWidth, viewHeight; + int alignX, alignY, alignType; + float dpi; + char pathFlag; + char defsFlag; + /** Blender breadscrum for layers. */ + char breadcrumb[NSVG_MAX_BREADCRUMB][64]; + /** Blender number of elements in breadscrum. */ + int breadcrumb_len; +} NSVGparser; + +static void nsvg__xformIdentity(float *t) +{ + t[0] = 1.0f; + t[1] = 0.0f; + t[2] = 0.0f; + t[3] = 1.0f; + t[4] = 0.0f; + t[5] = 0.0f; +} + +static void nsvg__xformSetTranslation(float *t, float tx, float ty) +{ + t[0] = 1.0f; + t[1] = 0.0f; + t[2] = 0.0f; + t[3] = 1.0f; + t[4] = tx; + t[5] = ty; +} + +static void nsvg__xformSetScale(float *t, float sx, float sy) +{ + t[0] = sx; + t[1] = 0.0f; + t[2] = 0.0f; + t[3] = sy; + t[4] = 0.0f; + t[5] = 0.0f; +} + +static void nsvg__xformSetSkewX(float *t, float a) +{ + t[0] = 1.0f; + t[1] = 0.0f; + t[2] = tanf(a); + t[3] = 1.0f; + t[4] = 0.0f; + t[5] = 0.0f; +} + +static void nsvg__xformSetSkewY(float *t, float a) +{ + t[0] = 1.0f; + t[1] = tanf(a); + t[2] = 0.0f; + t[3] = 1.0f; + t[4] = 0.0f; + t[5] = 0.0f; +} + +static void nsvg__xformSetRotation(float *t, float a) +{ + float cs = cosf(a), sn = sinf(a); + t[0] = cs; + t[1] = sn; + t[2] = -sn; + t[3] = cs; + t[4] = 0.0f; + t[5] = 0.0f; +} + +static void nsvg__xformMultiply(float *t, float *s) +{ + float t0 = t[0] * s[0] + t[1] * s[2]; + float t2 = t[2] * s[0] + t[3] * s[2]; + float t4 = t[4] * s[0] + t[5] * s[2] + s[4]; + t[1] = t[0] * s[1] + t[1] * s[3]; + t[3] = t[2] * s[1] + t[3] * s[3]; + t[5] = t[4] * s[1] + t[5] * s[3] + s[5]; + t[0] = t0; + t[2] = t2; + t[4] = t4; +} + +static void nsvg__xformInverse(float *inv, float *t) +{ + double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1]; + if (det > -1e-6 && det < 1e-6) { + nsvg__xformIdentity(t); + return; + } + invdet = 1.0 / det; + inv[0] = (float)(t[3] * invdet); + inv[2] = (float)(-t[2] * invdet); + inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet); + inv[1] = (float)(-t[1] * invdet); + inv[3] = (float)(t[0] * invdet); + inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet); +} + +static void nsvg__xformPremultiply(float *t, float *s) +{ + float s2[6]; + memcpy(s2, s, sizeof(float) * 6); + nsvg__xformMultiply(s2, t); + memcpy(t, s2, sizeof(float) * 6); +} + +static void nsvg__xformPoint(float *dx, float *dy, float x, float y, float *t) +{ + *dx = x * t[0] + y * t[2] + t[4]; + *dy = x * t[1] + y * t[3] + t[5]; +} + +static void nsvg__xformVec(float *dx, float *dy, float x, float y, float *t) +{ + *dx = x * t[0] + y * t[2]; + *dy = x * t[1] + y * t[3]; +} + +#define NSVG_EPSILON (1e-12) + +static int nsvg__ptInBounds(float *pt, float *bounds) +{ + return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3]; +} + +static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3) +{ + double it = 1.0 - t; + return it * it * it * p0 + 3.0 * it * it * t * p1 + 3.0 * it * t * t * p2 + t * t * t * p3; +} + +static void nsvg__curveBounds(float *bounds, float *curve) +{ + int i, j, count; + double roots[2], a, b, c, b2ac, t, v; + float *v0 = &curve[0]; + float *v1 = &curve[2]; + float *v2 = &curve[4]; + float *v3 = &curve[6]; + + // Start the bounding box by end points + bounds[0] = nsvg__minf(v0[0], v3[0]); + bounds[1] = nsvg__minf(v0[1], v3[1]); + bounds[2] = nsvg__maxf(v0[0], v3[0]); + bounds[3] = nsvg__maxf(v0[1], v3[1]); + + // Bezier curve fits inside the convex hull of it's control points. + // If control points are inside the bounds, we're done. + if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds)) + return; + + // Add bezier curve inflection points in X and Y. + for (i = 0; i < 2; i++) { + a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i]; + b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i]; + c = 3.0 * v1[i] - 3.0 * v0[i]; + count = 0; + if (fabs(a) < NSVG_EPSILON) { + if (fabs(b) > NSVG_EPSILON) { + t = -c / b; + if (t > NSVG_EPSILON && t < 1.0 - NSVG_EPSILON) + roots[count++] = t; + } + } + else { + b2ac = b * b - 4.0 * c * a; + if (b2ac > NSVG_EPSILON) { + t = (-b + sqrt(b2ac)) / (2.0 * a); + if (t > NSVG_EPSILON && t < 1.0 - NSVG_EPSILON) + roots[count++] = t; + t = (-b - sqrt(b2ac)) / (2.0 * a); + if (t > NSVG_EPSILON && t < 1.0 - NSVG_EPSILON) + roots[count++] = t; + } + } + for (j = 0; j < count; j++) { + v = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]); + bounds[0 + i] = nsvg__minf(bounds[0 + i], (float)v); + bounds[2 + i] = nsvg__maxf(bounds[2 + i], (float)v); + } + } +} + +static NSVGparser *nsvg__createParser() +{ + NSVGparser *p; + p = (NSVGparser *)malloc(sizeof(NSVGparser)); + if (p == NULL) + goto error; + memset(p, 0, sizeof(NSVGparser)); + + p->image = (NSVGimage *)malloc(sizeof(NSVGimage)); + if (p->image == NULL) + goto error; + memset(p->image, 0, sizeof(NSVGimage)); + + // Init style + nsvg__xformIdentity(p->attr[0].xform); + memset(p->attr[0].id, 0, sizeof p->attr[0].id); + p->attr[0].fillColor = NSVG_RGB(0, 0, 0); + p->attr[0].strokeColor = NSVG_RGB(0, 0, 0); + p->attr[0].opacity = 1; + p->attr[0].fillOpacity = 1; + p->attr[0].strokeOpacity = 1; + p->attr[0].stopOpacity = 1; + p->attr[0].strokeWidth = 1; + p->attr[0].strokeLineJoin = NSVG_JOIN_MITER; + p->attr[0].strokeLineCap = NSVG_CAP_BUTT; + p->attr[0].miterLimit = 4; + p->attr[0].fillRule = NSVG_FILLRULE_NONZERO; + p->attr[0].hasFill = 1; + p->attr[0].visible = 1; + + return p; + +error: + if (p) { + if (p->image) + free(p->image); + free(p); + } + return NULL; +} + +static void nsvg__deletePaths(NSVGpath *path) +{ + while (path) { + NSVGpath *next = path->next; + if (path->pts != NULL) + free(path->pts); + free(path); + path = next; + } +} + +static void nsvg__deletePaint(NSVGpaint *paint) +{ + if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT) + free(paint->gradient); +} + +static void nsvg__deleteGradientData(NSVGgradientData *grad) +{ + NSVGgradientData *next; + while (grad != NULL) { + next = grad->next; + free(grad->stops); + free(grad); + grad = next; + } +} + +static void nsvg__deleteParser(NSVGparser *p) +{ + if (p != NULL) { + nsvg__deletePaths(p->plist); + nsvg__deleteGradientData(p->gradients); + nsvgDelete(p->image); + free(p->pts); + free(p); + } +} + +static void nsvg__resetPath(NSVGparser *p) +{ + p->npts = 0; +} + +static void nsvg__addPoint(NSVGparser *p, float x, float y) +{ + if (p->npts + 1 > p->cpts) { + p->cpts = p->cpts ? p->cpts * 2 : 8; + p->pts = (float *)realloc(p->pts, p->cpts * 2 * sizeof(float)); + if (!p->pts) + return; + } + p->pts[p->npts * 2 + 0] = x; + p->pts[p->npts * 2 + 1] = y; + p->npts++; +} + +static void nsvg__moveTo(NSVGparser *p, float x, float y) +{ + if (p->npts > 0) { + p->pts[(p->npts - 1) * 2 + 0] = x; + p->pts[(p->npts - 1) * 2 + 1] = y; + } + else { + nsvg__addPoint(p, x, y); + } +} + +static void nsvg__lineTo(NSVGparser *p, float x, float y) +{ + float px, py, dx, dy; + if (p->npts > 0) { + px = p->pts[(p->npts - 1) * 2 + 0]; + py = p->pts[(p->npts - 1) * 2 + 1]; + dx = x - px; + dy = y - py; + nsvg__addPoint(p, px + dx / 3.0f, py + dy / 3.0f); + nsvg__addPoint(p, x - dx / 3.0f, y - dy / 3.0f); + nsvg__addPoint(p, x, y); + } +} + +static void nsvg__cubicBezTo( + NSVGparser *p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y) +{ + if (p->npts > 0) { + nsvg__addPoint(p, cpx1, cpy1); + nsvg__addPoint(p, cpx2, cpy2); + nsvg__addPoint(p, x, y); + } +} + +static NSVGattrib *nsvg__getAttr(NSVGparser *p) +{ + return &p->attr[p->attrHead]; +} + +static void nsvg__pushAttr(NSVGparser *p) +{ + if (p->attrHead < NSVG_MAX_ATTR - 1) { + p->attrHead++; + memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead - 1], sizeof(NSVGattrib)); + } +} + +static void nsvg__popAttr(NSVGparser *p) +{ + if (p->attrHead > 0) + p->attrHead--; +} + +static float nsvg__actualOrigX(NSVGparser *p) +{ + return p->viewMinx; +} + +static float nsvg__actualOrigY(NSVGparser *p) +{ + return p->viewMiny; +} + +static float nsvg__actualWidth(NSVGparser *p) +{ + return p->viewWidth; +} + +static float nsvg__actualHeight(NSVGparser *p) +{ + return p->viewHeight; +} + +static float nsvg__actualLength(NSVGparser *p) +{ + float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p); + return sqrtf(w * w + h * h) / sqrtf(2.0f); +} + +static float nsvg__convertToPixels(NSVGparser *p, NSVGcoordinate c, float orig, float length) +{ + NSVGattrib *attr = nsvg__getAttr(p); + switch (c.units) { + case NSVG_UNITS_USER: + return c.value; + case NSVG_UNITS_PX: + return c.value; + case NSVG_UNITS_PT: + return c.value / 72.0f * p->dpi; + case NSVG_UNITS_PC: + return c.value / 6.0f * p->dpi; + case NSVG_UNITS_MM: + return c.value / 25.4f * p->dpi; + case NSVG_UNITS_CM: + return c.value / 2.54f * p->dpi; + case NSVG_UNITS_IN: + return c.value * p->dpi; + case NSVG_UNITS_EM: + return c.value * attr->fontSize; + case NSVG_UNITS_EX: + return c.value * attr->fontSize * 0.52f; // x-height of Helvetica. + case NSVG_UNITS_PERCENT: + return orig + c.value / 100.0f * length; + default: + return c.value; + } + return c.value; +} + +static NSVGgradientData *nsvg__findGradientData(NSVGparser *p, const char *id) +{ + NSVGgradientData *grad = p->gradients; + if (id == NULL || *id == '\0') + return NULL; + while (grad != NULL) { + if (strcmp(grad->id, id) == 0) + return grad; + grad = grad->next; + } + return NULL; +} + +static NSVGgradient *nsvg__createGradient(NSVGparser *p, + const char *id, + const float *localBounds, + char *paintType) +{ + NSVGattrib *attr = nsvg__getAttr(p); + NSVGgradientData *data = NULL; + NSVGgradientData *ref = NULL; + NSVGgradientStop *stops = NULL; + NSVGgradient *grad; + float ox, oy, sw, sh, sl; + int nstops = 0; + int refIter; + + data = nsvg__findGradientData(p, id); + if (data == NULL) + return NULL; + + // TODO: use ref to fill in all unset values too. + ref = data; + refIter = 0; + while (ref != NULL) { + NSVGgradientData *nextRef = NULL; + if (stops == NULL && ref->stops != NULL) { + stops = ref->stops; + nstops = ref->nstops; + break; + } + nextRef = nsvg__findGradientData(p, ref->ref); + if (nextRef == ref) + break; // prevent infite loops on malformed data + ref = nextRef; + refIter++; + if (refIter > 32) + break; // prevent infite loops on malformed data + } + if (stops == NULL) + return NULL; + + grad = (NSVGgradient *)malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop) * (nstops - 1)); + if (grad == NULL) + return NULL; + + // The shape width and height. + if (data->units == NSVG_OBJECT_SPACE) { + ox = localBounds[0]; + oy = localBounds[1]; + sw = localBounds[2] - localBounds[0]; + sh = localBounds[3] - localBounds[1]; + } + else { + ox = nsvg__actualOrigX(p); + oy = nsvg__actualOrigY(p); + sw = nsvg__actualWidth(p); + sh = nsvg__actualHeight(p); + } + sl = sqrtf(sw * sw + sh * sh) / sqrtf(2.0f); + + if (data->type == NSVG_PAINT_LINEAR_GRADIENT) { + float x1, y1, x2, y2, dx, dy; + x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw); + y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh); + x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw); + y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh); + // Calculate transform aligned to the line + dx = x2 - x1; + dy = y2 - y1; + grad->xform[0] = dy; + grad->xform[1] = -dx; + grad->xform[2] = dx; + grad->xform[3] = dy; + grad->xform[4] = x1; + grad->xform[5] = y1; + } + else { + float cx, cy, fx, fy, r; + cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw); + cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh); + fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw); + fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh); + r = nsvg__convertToPixels(p, data->radial.r, 0, sl); + // Calculate transform aligned to the circle + grad->xform[0] = r; + grad->xform[1] = 0; + grad->xform[2] = 0; + grad->xform[3] = r; + grad->xform[4] = cx; + grad->xform[5] = cy; + grad->fx = fx / r; + grad->fy = fy / r; + } + + nsvg__xformMultiply(grad->xform, data->xform); + nsvg__xformMultiply(grad->xform, attr->xform); + + grad->spread = data->spread; + memcpy(grad->stops, stops, nstops * sizeof(NSVGgradientStop)); + grad->nstops = nstops; + + *paintType = data->type; + + return grad; +} + +static float nsvg__getAverageScale(float *t) +{ + float sx = sqrtf(t[0] * t[0] + t[2] * t[2]); + float sy = sqrtf(t[1] * t[1] + t[3] * t[3]); + return (sx + sy) * 0.5f; +} + +static void nsvg__getLocalBounds(float *bounds, NSVGshape *shape, float *xform) +{ + NSVGpath *path; + float curve[4 * 2], curveBounds[4]; + int i, first = 1; + for (path = shape->paths; path != NULL; path = path->next) { + nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform); + for (i = 0; i < path->npts - 1; i += 3) { + nsvg__xformPoint( + &curve[2], &curve[3], path->pts[(i + 1) * 2], path->pts[(i + 1) * 2 + 1], xform); + nsvg__xformPoint( + &curve[4], &curve[5], path->pts[(i + 2) * 2], path->pts[(i + 2) * 2 + 1], xform); + nsvg__xformPoint( + &curve[6], &curve[7], path->pts[(i + 3) * 2], path->pts[(i + 3) * 2 + 1], xform); + nsvg__curveBounds(curveBounds, curve); + if (first) { + bounds[0] = curveBounds[0]; + bounds[1] = curveBounds[1]; + bounds[2] = curveBounds[2]; + bounds[3] = curveBounds[3]; + first = 0; + } + else { + bounds[0] = nsvg__minf(bounds[0], curveBounds[0]); + bounds[1] = nsvg__minf(bounds[1], curveBounds[1]); + bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]); + bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]); + } + curve[0] = curve[6]; + curve[1] = curve[7]; + } + } +} + +static void nsvg__addShape(NSVGparser *p) +{ + NSVGattrib *attr = nsvg__getAttr(p); + float scale = 1.0f; + NSVGshape *shape; + NSVGpath *path; + int i; + + if (p->plist == NULL) + return; + + shape = (NSVGshape *)malloc(sizeof(NSVGshape)); + if (shape == NULL) + goto error; + memset(shape, 0, sizeof(NSVGshape)); + + memcpy(shape->id, attr->id, sizeof shape->id); + /* Copy parent id from breadcrumb. */ + if (p->breadcrumb_len > 0) { + memcpy(shape->id_parent, p->breadcrumb[0], sizeof shape->id_parent); + } + else { + memcpy(shape->id_parent, attr->id, sizeof shape->id_parent); + } + + scale = nsvg__getAverageScale(attr->xform); + shape->strokeWidth = attr->strokeWidth * scale; + shape->strokeDashOffset = attr->strokeDashOffset * scale; + shape->strokeDashCount = (char)attr->strokeDashCount; + for (i = 0; i < attr->strokeDashCount; i++) + shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale; + shape->strokeLineJoin = attr->strokeLineJoin; + shape->strokeLineCap = attr->strokeLineCap; + shape->miterLimit = attr->miterLimit; + shape->fillRule = attr->fillRule; + shape->opacity = attr->opacity; + + shape->paths = p->plist; + p->plist = NULL; + + // Calculate shape bounds + shape->bounds[0] = shape->paths->bounds[0]; + shape->bounds[1] = shape->paths->bounds[1]; + shape->bounds[2] = shape->paths->bounds[2]; + shape->bounds[3] = shape->paths->bounds[3]; + for (path = shape->paths->next; path != NULL; path = path->next) { + shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]); + shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]); + shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]); + shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]); + } + + // Set fill + if (attr->hasFill == 0) { + shape->fill.type = NSVG_PAINT_NONE; + } + else if (attr->hasFill == 1) { + shape->fill.type = NSVG_PAINT_COLOR; + shape->fill.color = attr->fillColor; + shape->fill.color |= (unsigned int)(attr->fillOpacity * 255) << 24; + } + else if (attr->hasFill == 2) { + float inv[6], localBounds[4]; + nsvg__xformInverse(inv, attr->xform); + nsvg__getLocalBounds(localBounds, shape, inv); + shape->fill.gradient = nsvg__createGradient( + p, attr->fillGradient, localBounds, &shape->fill.type); + if (shape->fill.gradient == NULL) { + shape->fill.type = NSVG_PAINT_NONE; + } + } + + // Set stroke + if (attr->hasStroke == 0) { + shape->stroke.type = NSVG_PAINT_NONE; + } + else if (attr->hasStroke == 1) { + shape->stroke.type = NSVG_PAINT_COLOR; + shape->stroke.color = attr->strokeColor; + shape->stroke.color |= (unsigned int)(attr->strokeOpacity * 255) << 24; + } + else if (attr->hasStroke == 2) { + float inv[6], localBounds[4]; + nsvg__xformInverse(inv, attr->xform); + nsvg__getLocalBounds(localBounds, shape, inv); + shape->stroke.gradient = nsvg__createGradient( + p, attr->strokeGradient, localBounds, &shape->stroke.type); + if (shape->stroke.gradient == NULL) + shape->stroke.type = NSVG_PAINT_NONE; + } + + // Set flags + shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00); + + // Add to tail + if (p->image->shapes == NULL) + p->image->shapes = shape; + else + p->shapesTail->next = shape; + p->shapesTail = shape; + + return; + +error: + if (shape) + free(shape); +} + +static void nsvg__addPath(NSVGparser *p, char closed) +{ + NSVGattrib *attr = nsvg__getAttr(p); + NSVGpath *path = NULL; + float bounds[4]; + float *curve; + int i; + + if (p->npts < 4) + return; + + if (closed) + nsvg__lineTo(p, p->pts[0], p->pts[1]); + + // Expect 1 + N*3 points (N = number of cubic bezier segments). + if ((p->npts % 3) != 1) + return; + + path = (NSVGpath *)malloc(sizeof(NSVGpath)); + if (path == NULL) + goto error; + memset(path, 0, sizeof(NSVGpath)); + + path->pts = (float *)malloc(p->npts * 2 * sizeof(float)); + if (path->pts == NULL) + goto error; + path->closed = closed; + path->npts = p->npts; + + // Transform path. + for (i = 0; i < p->npts; ++i) + nsvg__xformPoint( + &path->pts[i * 2], &path->pts[i * 2 + 1], p->pts[i * 2], p->pts[i * 2 + 1], attr->xform); + + // Find bounds + for (i = 0; i < path->npts - 1; i += 3) { + curve = &path->pts[i * 2]; + nsvg__curveBounds(bounds, curve); + if (i == 0) { + path->bounds[0] = bounds[0]; + path->bounds[1] = bounds[1]; + path->bounds[2] = bounds[2]; + path->bounds[3] = bounds[3]; + } + else { + path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]); + path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]); + path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]); + path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]); + } + } + + path->next = p->plist; + p->plist = path; + + return; + +error: + if (path != NULL) { + if (path->pts != NULL) + free(path->pts); + free(path); + } +} + +// We roll our own string to float because the std library one uses locale and messes things up. +static double nsvg__atof(const char *s) +{ + char *cur = (char *)s; + char *end = NULL; + double res = 0.0, sign = 1.0; + long long intPart = 0, fracPart = 0; + char hasIntPart = 0, hasFracPart = 0; + + // Parse optional sign + if (*cur == '+') { + cur++; + } + else if (*cur == '-') { + sign = -1; + cur++; + } + + // Parse integer part + if (nsvg__isdigit(*cur)) { + // Parse digit sequence + intPart = strtoll(cur, &end, 10); + if (cur != end) { + res = (double)intPart; + hasIntPart = 1; + cur = end; + } + } + + // Parse fractional part. + if (*cur == '.') { + cur++; // Skip '.' + if (nsvg__isdigit(*cur)) { + // Parse digit sequence + fracPart = strtoll(cur, &end, 10); + if (cur != end) { + res += (double)fracPart / pow(10.0, (double)(end - cur)); + hasFracPart = 1; + cur = end; + } + } + } + + // A valid number should have integer or fractional part. + if (!hasIntPart && !hasFracPart) + return 0.0; + + // Parse optional exponent + if (*cur == 'e' || *cur == 'E') { + long expPart = 0; + cur++; // skip 'E' + expPart = strtol(cur, &end, 10); // Parse digit sequence with sign + if (cur != end) { + res *= pow(10.0, (double)expPart); + } + } + + return res * sign; +} + +static const char *nsvg__parseNumber(const char *s, char *it, const int size) +{ + const int last = size - 1; + int i = 0; + + // sign + if (*s == '-' || *s == '+') { + if (i < last) + it[i++] = *s; + s++; + } + // integer part + while (*s && nsvg__isdigit(*s)) { + if (i < last) + it[i++] = *s; + s++; + } + if (*s == '.') { + // decimal point + if (i < last) + it[i++] = *s; + s++; + // fraction part + while (*s && nsvg__isdigit(*s)) { + if (i < last) + it[i++] = *s; + s++; + } + } + // exponent + if ((*s == 'e' || *s == 'E') && (s[1] != 'm' && s[1] != 'x')) { + if (i < last) + it[i++] = *s; + s++; + if (*s == '-' || *s == '+') { + if (i < last) + it[i++] = *s; + s++; + } + while (*s && nsvg__isdigit(*s)) { + if (i < last) + it[i++] = *s; + s++; + } + } + it[i] = '\0'; + + return s; +} + +static const char *nsvg__getNextPathItem(const char *s, char *it) +{ + it[0] = '\0'; + // Skip white spaces and commas + while (*s && (nsvg__isspace(*s) || *s == ',')) + s++; + if (!*s) + return s; + if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) { + s = nsvg__parseNumber(s, it, 64); + } + else { + // Parse command + it[0] = *s++; + it[1] = '\0'; + return s; + } + + return s; +} + +static unsigned int nsvg__parseColorHex(const char *str) +{ + unsigned int c = 0, r = 0, g = 0, b = 0; + int n = 0; + str++; // skip # + // Calculate number of characters. + while (str[n] && !nsvg__isspace(str[n])) + n++; + if (n == 6) { + sscanf(str, "%x", &c); + } + else if (n == 3) { + sscanf(str, "%x", &c); + c = (c & 0xf) | ((c & 0xf0) << 4) | ((c & 0xf00) << 8); + c |= c << 4; + } + r = (c >> 16) & 0xff; + g = (c >> 8) & 0xff; + b = c & 0xff; + return NSVG_RGB(r, g, b); +} + +static unsigned int nsvg__parseColorRGB(const char *str) +{ + int r = -1, g = -1, b = -1; + char s1[32] = "", s2[32] = ""; + sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b); + if (strchr(s1, '%')) { + return NSVG_RGB((r * 255) / 100, (g * 255) / 100, (b * 255) / 100); + } + else { + return NSVG_RGB(r, g, b); + } +} + +typedef struct NSVGNamedColor { + const char *name; + unsigned int color; +} NSVGNamedColor; + +NSVGNamedColor nsvg__colors[] = { + + {"red", NSVG_RGB(255, 0, 0)}, + {"green", NSVG_RGB(0, 128, 0)}, + {"blue", NSVG_RGB(0, 0, 255)}, + {"yellow", NSVG_RGB(255, 255, 0)}, + {"cyan", NSVG_RGB(0, 255, 255)}, + {"magenta", NSVG_RGB(255, 0, 255)}, + {"black", NSVG_RGB(0, 0, 0)}, + {"grey", NSVG_RGB(128, 128, 128)}, + {"gray", NSVG_RGB(128, 128, 128)}, + {"white", NSVG_RGB(255, 255, 255)}, + +#ifdef NANOSVG_ALL_COLOR_KEYWORDS + {"aliceblue", NSVG_RGB(240, 248, 255)}, + {"antiquewhite", NSVG_RGB(250, 235, 215)}, + {"aqua", NSVG_RGB(0, 255, 255)}, + {"aquamarine", NSVG_RGB(127, 255, 212)}, + {"azure", NSVG_RGB(240, 255, 255)}, + {"beige", NSVG_RGB(245, 245, 220)}, + {"bisque", NSVG_RGB(255, 228, 196)}, + {"blanchedalmond", NSVG_RGB(255, 235, 205)}, + {"blueviolet", NSVG_RGB(138, 43, 226)}, + {"brown", NSVG_RGB(165, 42, 42)}, + {"burlywood", NSVG_RGB(222, 184, 135)}, + {"cadetblue", NSVG_RGB(95, 158, 160)}, + {"chartreuse", NSVG_RGB(127, 255, 0)}, + {"chocolate", NSVG_RGB(210, 105, 30)}, + {"coral", NSVG_RGB(255, 127, 80)}, + {"cornflowerblue", NSVG_RGB(100, 149, 237)}, + {"cornsilk", NSVG_RGB(255, 248, 220)}, + {"crimson", NSVG_RGB(220, 20, 60)}, + {"darkblue", NSVG_RGB(0, 0, 139)}, + {"darkcyan", NSVG_RGB(0, 139, 139)}, + {"darkgoldenrod", NSVG_RGB(184, 134, 11)}, + {"darkgray", NSVG_RGB(169, 169, 169)}, + {"darkgreen", NSVG_RGB(0, 100, 0)}, + {"darkgrey", NSVG_RGB(169, 169, 169)}, + {"darkkhaki", NSVG_RGB(189, 183, 107)}, + {"darkmagenta", NSVG_RGB(139, 0, 139)}, + {"darkolivegreen", NSVG_RGB(85, 107, 47)}, + {"darkorange", NSVG_RGB(255, 140, 0)}, + {"darkorchid", NSVG_RGB(153, 50, 204)}, + {"darkred", NSVG_RGB(139, 0, 0)}, + {"darksalmon", NSVG_RGB(233, 150, 122)}, + {"darkseagreen", NSVG_RGB(143, 188, 143)}, + {"darkslateblue", NSVG_RGB(72, 61, 139)}, + {"darkslategray", NSVG_RGB(47, 79, 79)}, + {"darkslategrey", NSVG_RGB(47, 79, 79)}, + {"darkturquoise", NSVG_RGB(0, 206, 209)}, + {"darkviolet", NSVG_RGB(148, 0, 211)}, + {"deeppink", NSVG_RGB(255, 20, 147)}, + {"deepskyblue", NSVG_RGB(0, 191, 255)}, + {"dimgray", NSVG_RGB(105, 105, 105)}, + {"dimgrey", NSVG_RGB(105, 105, 105)}, + {"dodgerblue", NSVG_RGB(30, 144, 255)}, + {"firebrick", NSVG_RGB(178, 34, 34)}, + {"floralwhite", NSVG_RGB(255, 250, 240)}, + {"forestgreen", NSVG_RGB(34, 139, 34)}, + {"fuchsia", NSVG_RGB(255, 0, 255)}, + {"gainsboro", NSVG_RGB(220, 220, 220)}, + {"ghostwhite", NSVG_RGB(248, 248, 255)}, + {"gold", NSVG_RGB(255, 215, 0)}, + {"goldenrod", NSVG_RGB(218, 165, 32)}, + {"greenyellow", NSVG_RGB(173, 255, 47)}, + {"honeydew", NSVG_RGB(240, 255, 240)}, + {"hotpink", NSVG_RGB(255, 105, 180)}, + {"indianred", NSVG_RGB(205, 92, 92)}, + {"indigo", NSVG_RGB(75, 0, 130)}, + {"ivory", NSVG_RGB(255, 255, 240)}, + {"khaki", NSVG_RGB(240, 230, 140)}, + {"lavender", NSVG_RGB(230, 230, 250)}, + {"lavenderblush", NSVG_RGB(255, 240, 245)}, + {"lawngreen", NSVG_RGB(124, 252, 0)}, + {"lemonchiffon", NSVG_RGB(255, 250, 205)}, + {"lightblue", NSVG_RGB(173, 216, 230)}, + {"lightcoral", NSVG_RGB(240, 128, 128)}, + {"lightcyan", NSVG_RGB(224, 255, 255)}, + {"lightgoldenrodyellow", NSVG_RGB(250, 250, 210)}, + {"lightgray", NSVG_RGB(211, 211, 211)}, + {"lightgreen", NSVG_RGB(144, 238, 144)}, + {"lightgrey", NSVG_RGB(211, 211, 211)}, + {"lightpink", NSVG_RGB(255, 182, 193)}, + {"lightsalmon", NSVG_RGB(255, 160, 122)}, + {"lightseagreen", NSVG_RGB(32, 178, 170)}, + {"lightskyblue", NSVG_RGB(135, 206, 250)}, + {"lightslategray", NSVG_RGB(119, 136, 153)}, + {"lightslategrey", NSVG_RGB(119, 136, 153)}, + {"lightsteelblue", NSVG_RGB(176, 196, 222)}, + {"lightyellow", NSVG_RGB(255, 255, 224)}, + {"lime", NSVG_RGB(0, 255, 0)}, + {"limegreen", NSVG_RGB(50, 205, 50)}, + {"linen", NSVG_RGB(250, 240, 230)}, + {"maroon", NSVG_RGB(128, 0, 0)}, + {"mediumaquamarine", NSVG_RGB(102, 205, 170)}, + {"mediumblue", NSVG_RGB(0, 0, 205)}, + {"mediumorchid", NSVG_RGB(186, 85, 211)}, + {"mediumpurple", NSVG_RGB(147, 112, 219)}, + {"mediumseagreen", NSVG_RGB(60, 179, 113)}, + {"mediumslateblue", NSVG_RGB(123, 104, 238)}, + {"mediumspringgreen", NSVG_RGB(0, 250, 154)}, + {"mediumturquoise", NSVG_RGB(72, 209, 204)}, + {"mediumvioletred", NSVG_RGB(199, 21, 133)}, + {"midnightblue", NSVG_RGB(25, 25, 112)}, + {"mintcream", NSVG_RGB(245, 255, 250)}, + {"mistyrose", NSVG_RGB(255, 228, 225)}, + {"moccasin", NSVG_RGB(255, 228, 181)}, + {"navajowhite", NSVG_RGB(255, 222, 173)}, + {"navy", NSVG_RGB(0, 0, 128)}, + {"oldlace", NSVG_RGB(253, 245, 230)}, + {"olive", NSVG_RGB(128, 128, 0)}, + {"olivedrab", NSVG_RGB(107, 142, 35)}, + {"orange", NSVG_RGB(255, 165, 0)}, + {"orangered", NSVG_RGB(255, 69, 0)}, + {"orchid", NSVG_RGB(218, 112, 214)}, + {"palegoldenrod", NSVG_RGB(238, 232, 170)}, + {"palegreen", NSVG_RGB(152, 251, 152)}, + {"paleturquoise", NSVG_RGB(175, 238, 238)}, + {"palevioletred", NSVG_RGB(219, 112, 147)}, + {"papayawhip", NSVG_RGB(255, 239, 213)}, + {"peachpuff", NSVG_RGB(255, 218, 185)}, + {"peru", NSVG_RGB(205, 133, 63)}, + {"pink", NSVG_RGB(255, 192, 203)}, + {"plum", NSVG_RGB(221, 160, 221)}, + {"powderblue", NSVG_RGB(176, 224, 230)}, + {"purple", NSVG_RGB(128, 0, 128)}, + {"rosybrown", NSVG_RGB(188, 143, 143)}, + {"royalblue", NSVG_RGB(65, 105, 225)}, + {"saddlebrown", NSVG_RGB(139, 69, 19)}, + {"salmon", NSVG_RGB(250, 128, 114)}, + {"sandybrown", NSVG_RGB(244, 164, 96)}, + {"seagreen", NSVG_RGB(46, 139, 87)}, + {"seashell", NSVG_RGB(255, 245, 238)}, + {"sienna", NSVG_RGB(160, 82, 45)}, + {"silver", NSVG_RGB(192, 192, 192)}, + {"skyblue", NSVG_RGB(135, 206, 235)}, + {"slateblue", NSVG_RGB(106, 90, 205)}, + {"slategray", NSVG_RGB(112, 128, 144)}, + {"slategrey", NSVG_RGB(112, 128, 144)}, + {"snow", NSVG_RGB(255, 250, 250)}, + {"springgreen", NSVG_RGB(0, 255, 127)}, + {"steelblue", NSVG_RGB(70, 130, 180)}, + {"tan", NSVG_RGB(210, 180, 140)}, + {"teal", NSVG_RGB(0, 128, 128)}, + {"thistle", NSVG_RGB(216, 191, 216)}, + {"tomato", NSVG_RGB(255, 99, 71)}, + {"turquoise", NSVG_RGB(64, 224, 208)}, + {"violet", NSVG_RGB(238, 130, 238)}, + {"wheat", NSVG_RGB(245, 222, 179)}, + {"whitesmoke", NSVG_RGB(245, 245, 245)}, + {"yellowgreen", NSVG_RGB(154, 205, 50)}, +#endif +}; + +static unsigned int nsvg__parseColorName(const char *str) +{ + int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor); + + for (i = 0; i < ncolors; i++) { + if (strcmp(nsvg__colors[i].name, str) == 0) { + return nsvg__colors[i].color; + } + } + + return NSVG_RGB(128, 128, 128); +} + +static unsigned int nsvg__parseColor(const char *str) +{ + size_t len = 0; + while (*str == ' ') + ++str; + len = strlen(str); + if (len >= 1 && *str == '#') + return nsvg__parseColorHex(str); + else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(') + return nsvg__parseColorRGB(str); + return nsvg__parseColorName(str); +} + +static float nsvg__parseOpacity(const char *str) +{ + float val = nsvg__atof(str); + if (val < 0.0f) + val = 0.0f; + if (val > 1.0f) + val = 1.0f; + return val; +} + +static float nsvg__parseMiterLimit(const char *str) +{ + float val = nsvg__atof(str); + if (val < 0.0f) + val = 0.0f; + return val; +} + +static int nsvg__parseUnits(const char *units) +{ + if (units[0] == 'p' && units[1] == 'x') + return NSVG_UNITS_PX; + else if (units[0] == 'p' && units[1] == 't') + return NSVG_UNITS_PT; + else if (units[0] == 'p' && units[1] == 'c') + return NSVG_UNITS_PC; + else if (units[0] == 'm' && units[1] == 'm') + return NSVG_UNITS_MM; + else if (units[0] == 'c' && units[1] == 'm') + return NSVG_UNITS_CM; + else if (units[0] == 'i' && units[1] == 'n') + return NSVG_UNITS_IN; + else if (units[0] == '%') + return NSVG_UNITS_PERCENT; + else if (units[0] == 'e' && units[1] == 'm') + return NSVG_UNITS_EM; + else if (units[0] == 'e' && units[1] == 'x') + return NSVG_UNITS_EX; + return NSVG_UNITS_USER; +} + +static int nsvg__isCoordinate(const char *s) +{ + // optional sign + if (*s == '-' || *s == '+') + s++; + // must have at least one digit + return nsvg__isdigit(*s); +} + +static NSVGcoordinate nsvg__parseCoordinateRaw(const char *str) +{ + NSVGcoordinate coord = {0, NSVG_UNITS_USER}; + char buf[64]; + coord.units = nsvg__parseUnits(nsvg__parseNumber(str, buf, 64)); + coord.value = nsvg__atof(buf); + return coord; +} + +static NSVGcoordinate nsvg__coord(float v, int units) +{ + NSVGcoordinate coord = {v, units}; + return coord; +} + +static float nsvg__parseCoordinate(NSVGparser *p, const char *str, float orig, float length) +{ + NSVGcoordinate coord = nsvg__parseCoordinateRaw(str); + return nsvg__convertToPixels(p, coord, orig, length); +} + +static int nsvg__parseTransformArgs(const char *str, float *args, int maxNa, int *na) +{ + const char *end; + const char *ptr; + char it[64]; + + *na = 0; + ptr = str; + while (*ptr && *ptr != '(') + ++ptr; + if (*ptr == 0) + return 1; + end = ptr; + while (*end && *end != ')') + ++end; + if (*end == 0) + return 1; + + while (ptr < end) { + if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) { + if (*na >= maxNa) + return 0; + ptr = nsvg__parseNumber(ptr, it, 64); + args[(*na)++] = (float)nsvg__atof(it); + } + else { + ++ptr; + } + } + return (int)(end - str); +} + +static int nsvg__parseMatrix(float *xform, const char *str) +{ + float t[6]; + int na = 0; + int len = nsvg__parseTransformArgs(str, t, 6, &na); + if (na != 6) + return len; + memcpy(xform, t, sizeof(float) * 6); + return len; +} + +static int nsvg__parseTranslate(float *xform, const char *str) +{ + float args[2]; + float t[6]; + int na = 0; + int len = nsvg__parseTransformArgs(str, args, 2, &na); + if (na == 1) + args[1] = 0.0; + + nsvg__xformSetTranslation(t, args[0], args[1]); + memcpy(xform, t, sizeof(float) * 6); + return len; +} + +static int nsvg__parseScale(float *xform, const char *str) +{ + float args[2]; + int na = 0; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 2, &na); + if (na == 1) + args[1] = args[0]; + nsvg__xformSetScale(t, args[0], args[1]); + memcpy(xform, t, sizeof(float) * 6); + return len; +} + +static int nsvg__parseSkewX(float *xform, const char *str) +{ + float args[1]; + int na = 0; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 1, &na); + nsvg__xformSetSkewX(t, args[0] / 180.0f * NSVG_PI); + memcpy(xform, t, sizeof(float) * 6); + return len; +} + +static int nsvg__parseSkewY(float *xform, const char *str) +{ + float args[1]; + int na = 0; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 1, &na); + nsvg__xformSetSkewY(t, args[0] / 180.0f * NSVG_PI); + memcpy(xform, t, sizeof(float) * 6); + return len; +} + +static int nsvg__parseRotate(float *xform, const char *str) +{ + float args[3]; + int na = 0; + float m[6]; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 3, &na); + if (na == 1) + args[1] = args[2] = 0.0f; + nsvg__xformIdentity(m); + + if (na > 1) { + nsvg__xformSetTranslation(t, -args[1], -args[2]); + nsvg__xformMultiply(m, t); + } + + nsvg__xformSetRotation(t, args[0] / 180.0f * NSVG_PI); + nsvg__xformMultiply(m, t); + + if (na > 1) { + nsvg__xformSetTranslation(t, args[1], args[2]); + nsvg__xformMultiply(m, t); + } + + memcpy(xform, m, sizeof(float) * 6); + + return len; +} + +static void nsvg__parseTransform(float *xform, const char *str) +{ + float t[6]; + int len; + nsvg__xformIdentity(xform); + while (*str) { + if (strncmp(str, "matrix", 6) == 0) + len = nsvg__parseMatrix(t, str); + else if (strncmp(str, "translate", 9) == 0) + len = nsvg__parseTranslate(t, str); + else if (strncmp(str, "scale", 5) == 0) + len = nsvg__parseScale(t, str); + else if (strncmp(str, "rotate", 6) == 0) + len = nsvg__parseRotate(t, str); + else if (strncmp(str, "skewX", 5) == 0) + len = nsvg__parseSkewX(t, str); + else if (strncmp(str, "skewY", 5) == 0) + len = nsvg__parseSkewY(t, str); + else { + ++str; + continue; + } + if (len != 0) { + str += len; + } + else { + ++str; + continue; + } + + nsvg__xformPremultiply(xform, t); + } +} + +static void nsvg__parseUrl(char *id, const char *str) +{ + int i = 0; + str += 4; // "url("; + if (*str == '#') + str++; + while (i < 63 && *str != ')') { + id[i] = *str++; + i++; + } + id[i] = '\0'; +} + +static char nsvg__parseLineCap(const char *str) +{ + if (strcmp(str, "butt") == 0) + return NSVG_CAP_BUTT; + else if (strcmp(str, "round") == 0) + return NSVG_CAP_ROUND; + else if (strcmp(str, "square") == 0) + return NSVG_CAP_SQUARE; + // TODO: handle inherit. + return NSVG_CAP_BUTT; +} + +static char nsvg__parseLineJoin(const char *str) +{ + if (strcmp(str, "miter") == 0) + return NSVG_JOIN_MITER; + else if (strcmp(str, "round") == 0) + return NSVG_JOIN_ROUND; + else if (strcmp(str, "bevel") == 0) + return NSVG_JOIN_BEVEL; + // TODO: handle inherit. + return NSVG_JOIN_MITER; +} + +static char nsvg__parseFillRule(const char *str) +{ + if (strcmp(str, "nonzero") == 0) + return NSVG_FILLRULE_NONZERO; + else if (strcmp(str, "evenodd") == 0) + return NSVG_FILLRULE_EVENODD; + // TODO: handle inherit. + return NSVG_FILLRULE_NONZERO; +} + +static const char *nsvg__getNextDashItem(const char *s, char *it) +{ + int n = 0; + it[0] = '\0'; + // Skip white spaces and commas + while (*s && (nsvg__isspace(*s) || *s == ',')) + s++; + // Advance until whitespace, comma or end. + while (*s && (!nsvg__isspace(*s) && *s != ',')) { + if (n < 63) + it[n++] = *s; + s++; + } + it[n++] = '\0'; + return s; +} + +static int nsvg__parseStrokeDashArray(NSVGparser *p, const char *str, float *strokeDashArray) +{ + char item[64]; + int count = 0, i; + float sum = 0.0f; + + // Handle "none" + if (str[0] == 'n') + return 0; + + // Parse dashes + while (*str) { + str = nsvg__getNextDashItem(str, item); + if (!*item) + break; + if (count < NSVG_MAX_DASHES) + strokeDashArray[count++] = fabsf( + nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p))); + } + + for (i = 0; i < count; i++) + sum += strokeDashArray[i]; + if (sum <= 1e-6f) + count = 0; + + return count; +} + +static void nsvg__parseStyle(NSVGparser *p, const char *str); + +static int nsvg__parseAttr(NSVGparser *p, const char *name, const char *value) +{ + float xform[6]; + NSVGattrib *attr = nsvg__getAttr(p); + if (!attr) + return 0; + + if (strcmp(name, "style") == 0) { + nsvg__parseStyle(p, value); + } + else if (strcmp(name, "display") == 0) { + if (strcmp(value, "none") == 0) + attr->visible = 0; + // Don't reset ->visible on display:inline, one display:none hides the whole subtree + } + else if (strcmp(name, "fill") == 0) { + if (strcmp(value, "none") == 0) { + attr->hasFill = 0; + } + else if (strncmp(value, "url(", 4) == 0) { + attr->hasFill = 2; + nsvg__parseUrl(attr->fillGradient, value); + } + else { + attr->hasFill = 1; + attr->fillColor = nsvg__parseColor(value); + } + } + else if (strcmp(name, "opacity") == 0) { + attr->opacity = nsvg__parseOpacity(value); + } + else if (strcmp(name, "fill-opacity") == 0) { + attr->fillOpacity = nsvg__parseOpacity(value); + } + else if (strcmp(name, "stroke") == 0) { + if (strcmp(value, "none") == 0) { + attr->hasStroke = 0; + } + else if (strncmp(value, "url(", 4) == 0) { + attr->hasStroke = 2; + nsvg__parseUrl(attr->strokeGradient, value); + } + else { + attr->hasStroke = 1; + attr->strokeColor = nsvg__parseColor(value); + } + } + else if (strcmp(name, "stroke-width") == 0) { + attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); + } + else if (strcmp(name, "stroke-dasharray") == 0) { + attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray); + } + else if (strcmp(name, "stroke-dashoffset") == 0) { + attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); + } + else if (strcmp(name, "stroke-opacity") == 0) { + attr->strokeOpacity = nsvg__parseOpacity(value); + } + else if (strcmp(name, "stroke-linecap") == 0) { + attr->strokeLineCap = nsvg__parseLineCap(value); + } + else if (strcmp(name, "stroke-linejoin") == 0) { + attr->strokeLineJoin = nsvg__parseLineJoin(value); + } + else if (strcmp(name, "stroke-miterlimit") == 0) { + attr->miterLimit = nsvg__parseMiterLimit(value); + } + else if (strcmp(name, "fill-rule") == 0) { + attr->fillRule = nsvg__parseFillRule(value); + } + else if (strcmp(name, "font-size") == 0) { + attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); + } + else if (strcmp(name, "transform") == 0) { + nsvg__parseTransform(xform, value); + nsvg__xformPremultiply(attr->xform, xform); + } + else if (strcmp(name, "stop-color") == 0) { + attr->stopColor = nsvg__parseColor(value); + } + else if (strcmp(name, "stop-opacity") == 0) { + attr->stopOpacity = nsvg__parseOpacity(value); + } + else if (strcmp(name, "offset") == 0) { + attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f); + } + else if (strcmp(name, "id") == 0) { + strncpy(attr->id, value, 63); + attr->id[63] = '\0'; + } + else { + return 0; + } + return 1; +} + +static int nsvg__parseNameValue(NSVGparser *p, const char *start, const char *end) +{ + const char *str; + const char *val; + char name[512]; + char value[512]; + int n; + + str = start; + while (str < end && *str != ':') + ++str; + + val = str; + + // Right Trim + while (str > start && (*str == ':' || nsvg__isspace(*str))) + --str; + ++str; + + n = (int)(str - start); + if (n > 511) + n = 511; + if (n) + memcpy(name, start, n); + name[n] = 0; + + while (val < end && (*val == ':' || nsvg__isspace(*val))) + ++val; + + n = (int)(end - val); + if (n > 511) + n = 511; + if (n) + memcpy(value, val, n); + value[n] = 0; + + return nsvg__parseAttr(p, name, value); +} + +static void nsvg__parseStyle(NSVGparser *p, const char *str) +{ + const char *start; + const char *end; + + while (*str) { + // Left Trim + while (*str && nsvg__isspace(*str)) + ++str; + start = str; + while (*str && *str != ';') + ++str; + end = str; + + // Right Trim + while (end > start && (*end == ';' || nsvg__isspace(*end))) + --end; + ++end; + + nsvg__parseNameValue(p, start, end); + if (*str) + ++str; + } +} + +static void nsvg__parseAttribs(NSVGparser *p, const char **attr) +{ + int i; + for (i = 0; attr[i]; i += 2) { + if (strcmp(attr[i], "style") == 0) + nsvg__parseStyle(p, attr[i + 1]); + else + nsvg__parseAttr(p, attr[i], attr[i + 1]); + } +} + +static int nsvg__getArgsPerElement(char cmd) +{ + switch (cmd) { + case 'v': + case 'V': + case 'h': + case 'H': + return 1; + case 'm': + case 'M': + case 'l': + case 'L': + case 't': + case 'T': + return 2; + case 'q': + case 'Q': + case 's': + case 'S': + return 4; + case 'c': + case 'C': + return 6; + case 'a': + case 'A': + return 7; + case 'z': + case 'Z': + return 0; + } + return -1; +} + +static void nsvg__pathMoveTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) +{ + if (rel) { + *cpx += args[0]; + *cpy += args[1]; + } + else { + *cpx = args[0]; + *cpy = args[1]; + } + nsvg__moveTo(p, *cpx, *cpy); +} + +static void nsvg__pathLineTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) +{ + if (rel) { + *cpx += args[0]; + *cpy += args[1]; + } + else { + *cpx = args[0]; + *cpy = args[1]; + } + nsvg__lineTo(p, *cpx, *cpy); +} + +static void nsvg__pathHLineTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) +{ + if (rel) + *cpx += args[0]; + else + *cpx = args[0]; + nsvg__lineTo(p, *cpx, *cpy); +} + +static void nsvg__pathVLineTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) +{ + if (rel) + *cpy += args[0]; + else + *cpy = args[0]; + nsvg__lineTo(p, *cpx, *cpy); +} + +static void nsvg__pathCubicBezTo( + NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args, int rel) +{ + float x2, y2, cx1, cy1, cx2, cy2; + + if (rel) { + cx1 = *cpx + args[0]; + cy1 = *cpy + args[1]; + cx2 = *cpx + args[2]; + cy2 = *cpy + args[3]; + x2 = *cpx + args[4]; + y2 = *cpy + args[5]; + } + else { + cx1 = args[0]; + cy1 = args[1]; + cx2 = args[2]; + cy2 = args[3]; + x2 = args[4]; + y2 = args[5]; + } + + nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2); + + *cpx2 = cx2; + *cpy2 = cy2; + *cpx = x2; + *cpy = y2; +} + +static void nsvg__pathCubicBezShortTo( + NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args, int rel) +{ + float x1, y1, x2, y2, cx1, cy1, cx2, cy2; + + x1 = *cpx; + y1 = *cpy; + if (rel) { + cx2 = *cpx + args[0]; + cy2 = *cpy + args[1]; + x2 = *cpx + args[2]; + y2 = *cpy + args[3]; + } + else { + cx2 = args[0]; + cy2 = args[1]; + x2 = args[2]; + y2 = args[3]; + } + + cx1 = 2 * x1 - *cpx2; + cy1 = 2 * y1 - *cpy2; + + nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2); + + *cpx2 = cx2; + *cpy2 = cy2; + *cpx = x2; + *cpy = y2; +} + +static void nsvg__pathQuadBezTo( + NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args, int rel) +{ + float x1, y1, x2, y2, cx, cy; + float cx1, cy1, cx2, cy2; + + x1 = *cpx; + y1 = *cpy; + if (rel) { + cx = *cpx + args[0]; + cy = *cpy + args[1]; + x2 = *cpx + args[2]; + y2 = *cpy + args[3]; + } + else { + cx = args[0]; + cy = args[1]; + x2 = args[2]; + y2 = args[3]; + } + + // Convert to cubic bezier + cx1 = x1 + 2.0f / 3.0f * (cx - x1); + cy1 = y1 + 2.0f / 3.0f * (cy - y1); + cx2 = x2 + 2.0f / 3.0f * (cx - x2); + cy2 = y2 + 2.0f / 3.0f * (cy - y2); + + nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2); + + *cpx2 = cx; + *cpy2 = cy; + *cpx = x2; + *cpy = y2; +} + +static void nsvg__pathQuadBezShortTo( + NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args, int rel) +{ + float x1, y1, x2, y2, cx, cy; + float cx1, cy1, cx2, cy2; + + x1 = *cpx; + y1 = *cpy; + if (rel) { + x2 = *cpx + args[0]; + y2 = *cpy + args[1]; + } + else { + x2 = args[0]; + y2 = args[1]; + } + + cx = 2 * x1 - *cpx2; + cy = 2 * y1 - *cpy2; + + // Convert to cubix bezier + cx1 = x1 + 2.0f / 3.0f * (cx - x1); + cy1 = y1 + 2.0f / 3.0f * (cy - y1); + cx2 = x2 + 2.0f / 3.0f * (cx - x2); + cy2 = y2 + 2.0f / 3.0f * (cy - y2); + + nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2); + + *cpx2 = cx; + *cpy2 = cy; + *cpx = x2; + *cpy = y2; +} + +static float nsvg__sqr(float x) +{ + return x * x; +} +static float nsvg__vmag(float x, float y) +{ + return sqrtf(x * x + y * y); +} + +static float nsvg__vecrat(float ux, float uy, float vx, float vy) +{ + return (ux * vx + uy * vy) / (nsvg__vmag(ux, uy) * nsvg__vmag(vx, vy)); +} + +static float nsvg__vecang(float ux, float uy, float vx, float vy) +{ + float r = nsvg__vecrat(ux, uy, vx, vy); + if (r < -1.0f) + r = -1.0f; + if (r > 1.0f) + r = 1.0f; + return ((ux * vy < uy * vx) ? -1.0f : 1.0f) * acosf(r); +} + +static void nsvg__pathArcTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) +{ + // Ported from canvg (https://code.google.com/p/canvg/) + float rx, ry, rotx; + float x1, y1, x2, y2, cx, cy, dx, dy, d; + float x1p, y1p, cxp, cyp, s, sa, sb; + float ux, uy, vx, vy, a1, da; + float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6]; + float sinrx, cosrx; + int fa, fs; + int i, ndivs; + float hda, kappa; + + rx = fabsf(args[0]); // y radius + ry = fabsf(args[1]); // x radius + rotx = args[2] / 180.0f * NSVG_PI; // x rotation angle + fa = fabsf(args[3]) > 1e-6 ? 1 : 0; // Large arc + fs = fabsf(args[4]) > 1e-6 ? 1 : 0; // Sweep direction + x1 = *cpx; // start point + y1 = *cpy; + if (rel) { // end point + x2 = *cpx + args[5]; + y2 = *cpy + args[6]; + } + else { + x2 = args[5]; + y2 = args[6]; + } + + dx = x1 - x2; + dy = y1 - y2; + d = sqrtf(dx * dx + dy * dy); + if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) { + // The arc degenerates to a line + nsvg__lineTo(p, x2, y2); + *cpx = x2; + *cpy = y2; + return; + } + + sinrx = sinf(rotx); + cosrx = cosf(rotx); + + // Convert to center point parameterization. + // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes + // 1) Compute x1', y1' + x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f; + y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f; + d = nsvg__sqr(x1p) / nsvg__sqr(rx) + nsvg__sqr(y1p) / nsvg__sqr(ry); + if (d > 1) { + d = sqrtf(d); + rx *= d; + ry *= d; + } + // 2) Compute cx', cy' + s = 0.0f; + sa = nsvg__sqr(rx) * nsvg__sqr(ry) - nsvg__sqr(rx) * nsvg__sqr(y1p) - + nsvg__sqr(ry) * nsvg__sqr(x1p); + sb = nsvg__sqr(rx) * nsvg__sqr(y1p) + nsvg__sqr(ry) * nsvg__sqr(x1p); + if (sa < 0.0f) + sa = 0.0f; + if (sb > 0.0f) + s = sqrtf(sa / sb); + if (fa == fs) + s = -s; + cxp = s * rx * y1p / ry; + cyp = s * -ry * x1p / rx; + + // 3) Compute cx,cy from cx',cy' + cx = (x1 + x2) / 2.0f + cosrx * cxp - sinrx * cyp; + cy = (y1 + y2) / 2.0f + sinrx * cxp + cosrx * cyp; + + // 4) Calculate theta1, and delta theta. + ux = (x1p - cxp) / rx; + uy = (y1p - cyp) / ry; + vx = (-x1p - cxp) / rx; + vy = (-y1p - cyp) / ry; + a1 = nsvg__vecang(1.0f, 0.0f, ux, uy); // Initial angle + da = nsvg__vecang(ux, uy, vx, vy); // Delta angle + + // if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI; + // if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0; + + if (fs == 0 && da > 0) + da -= 2 * NSVG_PI; + else if (fs == 1 && da < 0) + da += 2 * NSVG_PI; + + // Approximate the arc using cubic spline segments. + t[0] = cosrx; + t[1] = sinrx; + t[2] = -sinrx; + t[3] = cosrx; + t[4] = cx; + t[5] = cy; + + // Split arc into max 90 degree segments. + // The loop assumes an iteration per end point (including start and end), this +1. + ndivs = (int)(fabsf(da) / (NSVG_PI * 0.5f) + 1.0f); + hda = (da / (float)ndivs) / 2.0f; + kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda)); + if (da < 0.0f) + kappa = -kappa; + + for (i = 0; i <= ndivs; i++) { + a = a1 + da * ((float)i / (float)ndivs); + dx = cosf(a); + dy = sinf(a); + nsvg__xformPoint(&x, &y, dx * rx, dy * ry, t); // position + nsvg__xformVec(&tanx, &tany, -dy * rx * kappa, dx * ry * kappa, t); // tangent + if (i > 0) + nsvg__cubicBezTo(p, px + ptanx, py + ptany, x - tanx, y - tany, x, y); + px = x; + py = y; + ptanx = tanx; + ptany = tany; + } + + *cpx = x2; + *cpy = y2; +} + +static void nsvg__parsePath(NSVGparser *p, const char **attr) +{ + const char *s = NULL; + char cmd = '\0'; + float args[10]; + int nargs; + int rargs = 0; + char initPoint; + float cpx, cpy, cpx2, cpy2; + const char *tmp[4]; + char closedFlag; + int i; + char item[64]; + + for (i = 0; attr[i]; i += 2) { + if (strcmp(attr[i], "d") == 0) { + s = attr[i + 1]; + } + else { + tmp[0] = attr[i]; + tmp[1] = attr[i + 1]; + tmp[2] = 0; + tmp[3] = 0; + nsvg__parseAttribs(p, tmp); + } + } + + if (s) { + nsvg__resetPath(p); + cpx = 0; + cpy = 0; + cpx2 = 0; + cpy2 = 0; + initPoint = 0; + closedFlag = 0; + nargs = 0; + + while (*s) { + s = nsvg__getNextPathItem(s, item); + if (!*item) + break; + if (cmd != '\0' && nsvg__isCoordinate(item)) { + if (nargs < 10) + args[nargs++] = (float)nsvg__atof(item); + if (nargs >= rargs) { + switch (cmd) { + case 'm': + case 'M': + nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0); + // Moveto can be followed by multiple coordinate pairs, + // which should be treated as linetos. + cmd = (cmd == 'm') ? 'l' : 'L'; + rargs = nsvg__getArgsPerElement(cmd); + cpx2 = cpx; + cpy2 = cpy; + initPoint = 1; + break; + case 'l': + case 'L': + nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0); + cpx2 = cpx; + cpy2 = cpy; + break; + case 'H': + case 'h': + nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0); + cpx2 = cpx; + cpy2 = cpy; + break; + case 'V': + case 'v': + nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0); + cpx2 = cpx; + cpy2 = cpy; + break; + case 'C': + case 'c': + nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0); + break; + case 'S': + case 's': + nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0); + break; + case 'Q': + case 'q': + nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0); + break; + case 'T': + case 't': + nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0); + break; + case 'A': + case 'a': + nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0); + cpx2 = cpx; + cpy2 = cpy; + break; + default: + if (nargs >= 2) { + cpx = args[nargs - 2]; + cpy = args[nargs - 1]; + cpx2 = cpx; + cpy2 = cpy; + } + break; + } + nargs = 0; + } + } + else { + cmd = item[0]; + if (cmd == 'M' || cmd == 'm') { + // Commit path. + if (p->npts > 0) + nsvg__addPath(p, closedFlag); + // Start new subpath. + nsvg__resetPath(p); + closedFlag = 0; + nargs = 0; + } + else if (initPoint == 0) { + // Do not allow other commands until initial point has been set (moveTo called once). + cmd = '\0'; + } + if (cmd == 'Z' || cmd == 'z') { + closedFlag = 1; + // Commit path. + if (p->npts > 0) { + // Move current point to first point + cpx = p->pts[0]; + cpy = p->pts[1]; + cpx2 = cpx; + cpy2 = cpy; + nsvg__addPath(p, closedFlag); + } + // Start new subpath. + nsvg__resetPath(p); + nsvg__moveTo(p, cpx, cpy); + closedFlag = 0; + nargs = 0; + } + rargs = nsvg__getArgsPerElement(cmd); + if (rargs == -1) { + // Command not recognized + cmd = '\0'; + rargs = 0; + } + } + } + // Commit path. + if (p->npts) + nsvg__addPath(p, closedFlag); + } + + nsvg__addShape(p); +} + +static void nsvg__parseRect(NSVGparser *p, const char **attr) +{ + float x = 0.0f; + float y = 0.0f; + float w = 0.0f; + float h = 0.0f; + float rx = -1.0f; // marks not set + float ry = -1.0f; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "x") == 0) + x = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y") == 0) + y = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "width") == 0) + w = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p)); + if (strcmp(attr[i], "height") == 0) + h = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p)); + if (strcmp(attr[i], "rx") == 0) + rx = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p))); + if (strcmp(attr[i], "ry") == 0) + ry = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p))); + } + } + + if (rx < 0.0f && ry > 0.0f) + rx = ry; + if (ry < 0.0f && rx > 0.0f) + ry = rx; + if (rx < 0.0f) + rx = 0.0f; + if (ry < 0.0f) + ry = 0.0f; + if (rx > w / 2.0f) + rx = w / 2.0f; + if (ry > h / 2.0f) + ry = h / 2.0f; + + if (w != 0.0f && h != 0.0f) { + nsvg__resetPath(p); + + if (rx < 0.00001f || ry < 0.0001f) { + nsvg__moveTo(p, x, y); + nsvg__lineTo(p, x + w, y); + nsvg__lineTo(p, x + w, y + h); + nsvg__lineTo(p, x, y + h); + } + else { + // Rounded rectangle + nsvg__moveTo(p, x + rx, y); + nsvg__lineTo(p, x + w - rx, y); + nsvg__cubicBezTo(p, + x + w - rx * (1 - NSVG_KAPPA90), + y, + x + w, + y + ry * (1 - NSVG_KAPPA90), + x + w, + y + ry); + nsvg__lineTo(p, x + w, y + h - ry); + nsvg__cubicBezTo(p, + x + w, + y + h - ry * (1 - NSVG_KAPPA90), + x + w - rx * (1 - NSVG_KAPPA90), + y + h, + x + w - rx, + y + h); + nsvg__lineTo(p, x + rx, y + h); + nsvg__cubicBezTo(p, + x + rx * (1 - NSVG_KAPPA90), + y + h, + x, + y + h - ry * (1 - NSVG_KAPPA90), + x, + y + h - ry); + nsvg__lineTo(p, x, y + ry); + nsvg__cubicBezTo( + p, x, y + ry * (1 - NSVG_KAPPA90), x + rx * (1 - NSVG_KAPPA90), y, x + rx, y); + } + + nsvg__addPath(p, 1); + + nsvg__addShape(p); + } +} + +static void nsvg__parseCircle(NSVGparser *p, const char **attr) +{ + float cx = 0.0f; + float cy = 0.0f; + float r = 0.0f; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "cx") == 0) + cx = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "cy") == 0) + cy = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "r") == 0) + r = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualLength(p))); + } + } + + if (r > 0.0f) { + nsvg__resetPath(p); + + nsvg__moveTo(p, cx + r, cy); + nsvg__cubicBezTo(p, cx + r, cy + r * NSVG_KAPPA90, cx + r * NSVG_KAPPA90, cy + r, cx, cy + r); + nsvg__cubicBezTo(p, cx - r * NSVG_KAPPA90, cy + r, cx - r, cy + r * NSVG_KAPPA90, cx - r, cy); + nsvg__cubicBezTo(p, cx - r, cy - r * NSVG_KAPPA90, cx - r * NSVG_KAPPA90, cy - r, cx, cy - r); + nsvg__cubicBezTo(p, cx + r * NSVG_KAPPA90, cy - r, cx + r, cy - r * NSVG_KAPPA90, cx + r, cy); + + nsvg__addPath(p, 1); + + nsvg__addShape(p); + } +} + +static void nsvg__parseEllipse(NSVGparser *p, const char **attr) +{ + float cx = 0.0f; + float cy = 0.0f; + float rx = 0.0f; + float ry = 0.0f; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "cx") == 0) + cx = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "cy") == 0) + cy = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "rx") == 0) + rx = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p))); + if (strcmp(attr[i], "ry") == 0) + ry = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p))); + } + } + + if (rx > 0.0f && ry > 0.0f) { + + nsvg__resetPath(p); + + nsvg__moveTo(p, cx + rx, cy); + nsvg__cubicBezTo( + p, cx + rx, cy + ry * NSVG_KAPPA90, cx + rx * NSVG_KAPPA90, cy + ry, cx, cy + ry); + nsvg__cubicBezTo( + p, cx - rx * NSVG_KAPPA90, cy + ry, cx - rx, cy + ry * NSVG_KAPPA90, cx - rx, cy); + nsvg__cubicBezTo( + p, cx - rx, cy - ry * NSVG_KAPPA90, cx - rx * NSVG_KAPPA90, cy - ry, cx, cy - ry); + nsvg__cubicBezTo( + p, cx + rx * NSVG_KAPPA90, cy - ry, cx + rx, cy - ry * NSVG_KAPPA90, cx + rx, cy); + + nsvg__addPath(p, 1); + + nsvg__addShape(p); + } +} + +static void nsvg__parseLine(NSVGparser *p, const char **attr) +{ + float x1 = 0.0; + float y1 = 0.0; + float x2 = 0.0; + float y2 = 0.0; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "x1") == 0) + x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y1") == 0) + y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "x2") == 0) + x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y2") == 0) + y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + } + } + + nsvg__resetPath(p); + + nsvg__moveTo(p, x1, y1); + nsvg__lineTo(p, x2, y2); + + nsvg__addPath(p, 0); + + nsvg__addShape(p); +} + +static void nsvg__parsePoly(NSVGparser *p, const char **attr, int closeFlag) +{ + int i; + const char *s; + float args[2]; + int nargs, npts = 0; + char item[64]; + + nsvg__resetPath(p); + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "points") == 0) { + s = attr[i + 1]; + nargs = 0; + while (*s) { + s = nsvg__getNextPathItem(s, item); + args[nargs++] = (float)nsvg__atof(item); + if (nargs >= 2) { + if (npts == 0) + nsvg__moveTo(p, args[0], args[1]); + else + nsvg__lineTo(p, args[0], args[1]); + nargs = 0; + npts++; + } + } + } + } + } + + nsvg__addPath(p, (char)closeFlag); + + nsvg__addShape(p); +} + +static void nsvg__parseSVG(NSVGparser *p, const char **attr) +{ + int i; + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "width") == 0) { + p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f); + } + else if (strcmp(attr[i], "height") == 0) { + p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f); + } + else if (strcmp(attr[i], "viewBox") == 0) { + const char *s = attr[i + 1]; + char buf[64]; + s = nsvg__parseNumber(s, buf, 64); + p->viewMinx = nsvg__atof(buf); + while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) + s++; + if (!*s) + return; + s = nsvg__parseNumber(s, buf, 64); + p->viewMiny = nsvg__atof(buf); + while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) + s++; + if (!*s) + return; + s = nsvg__parseNumber(s, buf, 64); + p->viewWidth = nsvg__atof(buf); + while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) + s++; + if (!*s) + return; + s = nsvg__parseNumber(s, buf, 64); + p->viewHeight = nsvg__atof(buf); + } + else if (strcmp(attr[i], "preserveAspectRatio") == 0) { + if (strstr(attr[i + 1], "none") != 0) { + // No uniform scaling + p->alignType = NSVG_ALIGN_NONE; + } + else { + // Parse X align + if (strstr(attr[i + 1], "xMin") != 0) + p->alignX = NSVG_ALIGN_MIN; + else if (strstr(attr[i + 1], "xMid") != 0) + p->alignX = NSVG_ALIGN_MID; + else if (strstr(attr[i + 1], "xMax") != 0) + p->alignX = NSVG_ALIGN_MAX; + // Parse X align + if (strstr(attr[i + 1], "yMin") != 0) + p->alignY = NSVG_ALIGN_MIN; + else if (strstr(attr[i + 1], "yMid") != 0) + p->alignY = NSVG_ALIGN_MID; + else if (strstr(attr[i + 1], "yMax") != 0) + p->alignY = NSVG_ALIGN_MAX; + // Parse meet/slice + p->alignType = NSVG_ALIGN_MEET; + if (strstr(attr[i + 1], "slice") != 0) + p->alignType = NSVG_ALIGN_SLICE; + } + } + } + } +} + +static void nsvg__parseGradient(NSVGparser *p, const char **attr, char type) +{ + int i; + NSVGgradientData *grad = (NSVGgradientData *)malloc(sizeof(NSVGgradientData)); + if (grad == NULL) + return; + memset(grad, 0, sizeof(NSVGgradientData)); + grad->units = NSVG_OBJECT_SPACE; + grad->type = type; + if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) { + grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT); + grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + } + else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) { + grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + } + + nsvg__xformIdentity(grad->xform); + + for (i = 0; attr[i]; i += 2) { + if (strcmp(attr[i], "id") == 0) { + strncpy(grad->id, attr[i + 1], 63); + grad->id[63] = '\0'; + } + else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "gradientUnits") == 0) { + if (strcmp(attr[i + 1], "objectBoundingBox") == 0) + grad->units = NSVG_OBJECT_SPACE; + else + grad->units = NSVG_USER_SPACE; + } + else if (strcmp(attr[i], "gradientTransform") == 0) { + nsvg__parseTransform(grad->xform, attr[i + 1]); + } + else if (strcmp(attr[i], "cx") == 0) { + grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]); + } + else if (strcmp(attr[i], "cy") == 0) { + grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]); + } + else if (strcmp(attr[i], "r") == 0) { + grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]); + } + else if (strcmp(attr[i], "fx") == 0) { + grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]); + } + else if (strcmp(attr[i], "fy") == 0) { + grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]); + } + else if (strcmp(attr[i], "x1") == 0) { + grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]); + } + else if (strcmp(attr[i], "y1") == 0) { + grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]); + } + else if (strcmp(attr[i], "x2") == 0) { + grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]); + } + else if (strcmp(attr[i], "y2") == 0) { + grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]); + } + else if (strcmp(attr[i], "spreadMethod") == 0) { + if (strcmp(attr[i + 1], "pad") == 0) + grad->spread = NSVG_SPREAD_PAD; + else if (strcmp(attr[i + 1], "reflect") == 0) + grad->spread = NSVG_SPREAD_REFLECT; + else if (strcmp(attr[i + 1], "repeat") == 0) + grad->spread = NSVG_SPREAD_REPEAT; + } + else if (strcmp(attr[i], "xlink:href") == 0) { + const char *href = attr[i + 1]; + strncpy(grad->ref, href + 1, 62); + grad->ref[62] = '\0'; + } + } + } + + grad->next = p->gradients; + p->gradients = grad; +} + +static void nsvg__parseGradientStop(NSVGparser *p, const char **attr) +{ + NSVGattrib *curAttr = nsvg__getAttr(p); + NSVGgradientData *grad; + NSVGgradientStop *stop; + int i, idx; + + curAttr->stopOffset = 0; + curAttr->stopColor = 0; + curAttr->stopOpacity = 1.0f; + + for (i = 0; attr[i]; i += 2) { + nsvg__parseAttr(p, attr[i], attr[i + 1]); + } + + // Add stop to the last gradient. + grad = p->gradients; + if (grad == NULL) + return; + + grad->nstops++; + grad->stops = (NSVGgradientStop *)realloc(grad->stops, sizeof(NSVGgradientStop) * grad->nstops); + if (grad->stops == NULL) + return; + + // Insert + idx = grad->nstops - 1; + for (i = 0; i < grad->nstops - 1; i++) { + if (curAttr->stopOffset < grad->stops[i].offset) { + idx = i; + break; + } + } + if (idx != grad->nstops - 1) { + for (i = grad->nstops - 1; i > idx; i--) + grad->stops[i] = grad->stops[i - 1]; + } + + stop = &grad->stops[idx]; + stop->color = curAttr->stopColor; + stop->color |= (unsigned int)(curAttr->stopOpacity * 255) << 24; + stop->offset = curAttr->stopOffset; +} + +static void nsvg__startElement(void *ud, const char *el, const char **attr) +{ + NSVGparser *p = (NSVGparser *)ud; + + if (p->defsFlag) { + // Skip everything but gradients in defs + if (strcmp(el, "linearGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT); + } + else if (strcmp(el, "radialGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT); + } + else if (strcmp(el, "stop") == 0) { + nsvg__parseGradientStop(p, attr); + } + return; + } + + if (strcmp(el, "g") == 0) { + nsvg__pushAttr(p); + nsvg__parseAttribs(p, attr); + + /* Save the breadcrumb of groups. */ + if (p->breadcrumb_len < NSVG_MAX_BREADCRUMB) { + NSVGattrib *attr_id = nsvg__getAttr(p); + memcpy( + p->breadcrumb[p->breadcrumb_len], attr_id->id, sizeof(p->breadcrumb[p->breadcrumb_len])); + p->breadcrumb_len++; + } + } + else if (strcmp(el, "path") == 0) { + if (p->pathFlag) // Do not allow nested paths. + return; + nsvg__pushAttr(p); + nsvg__parsePath(p, attr); + nsvg__popAttr(p); + } + else if (strcmp(el, "rect") == 0) { + nsvg__pushAttr(p); + nsvg__parseRect(p, attr); + nsvg__popAttr(p); + } + else if (strcmp(el, "circle") == 0) { + nsvg__pushAttr(p); + nsvg__parseCircle(p, attr); + nsvg__popAttr(p); + } + else if (strcmp(el, "ellipse") == 0) { + nsvg__pushAttr(p); + nsvg__parseEllipse(p, attr); + nsvg__popAttr(p); + } + else if (strcmp(el, "line") == 0) { + nsvg__pushAttr(p); + nsvg__parseLine(p, attr); + nsvg__popAttr(p); + } + else if (strcmp(el, "polyline") == 0) { + nsvg__pushAttr(p); + nsvg__parsePoly(p, attr, 0); + nsvg__popAttr(p); + } + else if (strcmp(el, "polygon") == 0) { + nsvg__pushAttr(p); + nsvg__parsePoly(p, attr, 1); + nsvg__popAttr(p); + } + else if (strcmp(el, "linearGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT); + } + else if (strcmp(el, "radialGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT); + } + else if (strcmp(el, "stop") == 0) { + nsvg__parseGradientStop(p, attr); + } + else if (strcmp(el, "defs") == 0) { + p->defsFlag = 1; + } + else if (strcmp(el, "svg") == 0) { + nsvg__parseSVG(p, attr); + } +} + +static void nsvg__endElement(void *ud, const char *el) +{ + NSVGparser *p = (NSVGparser *)ud; + + if (strcmp(el, "g") == 0) { + /* Remove the breadcrumb level. */ + if (p->breadcrumb_len > 0) { + p->breadcrumb[p->breadcrumb_len - 1][0] = '\0'; + p->breadcrumb_len--; + } + + nsvg__popAttr(p); + } + else if (strcmp(el, "path") == 0) { + p->pathFlag = 0; + } + else if (strcmp(el, "defs") == 0) { + p->defsFlag = 0; + } +} + +static void nsvg__content(void *ud, const char *s) +{ + NSVG_NOTUSED(ud); + NSVG_NOTUSED(s); + // empty +} + +static void nsvg__imageBounds(NSVGparser *p, float *bounds) +{ + NSVGshape *shape; + shape = p->image->shapes; + if (shape == NULL) { + bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0; + return; + } + bounds[0] = shape->bounds[0]; + bounds[1] = shape->bounds[1]; + bounds[2] = shape->bounds[2]; + bounds[3] = shape->bounds[3]; + for (shape = shape->next; shape != NULL; shape = shape->next) { + bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]); + bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]); + bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]); + bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]); + } +} + +static float nsvg__viewAlign(float content, float container, int type) +{ + if (type == NSVG_ALIGN_MIN) + return 0; + else if (type == NSVG_ALIGN_MAX) + return container - content; + // mid + return (container - content) * 0.5f; +} + +static void nsvg__scaleGradient(NSVGgradient *grad, float tx, float ty, float sx, float sy) +{ + float t[6]; + nsvg__xformSetTranslation(t, tx, ty); + nsvg__xformMultiply(grad->xform, t); + + nsvg__xformSetScale(t, sx, sy); + nsvg__xformMultiply(grad->xform, t); +} + +static void nsvg__scaleToViewbox(NSVGparser *p, const char *units) +{ + NSVGshape *shape; + NSVGpath *path; + float tx, ty, sx, sy, us, bounds[4], t[6], avgs; + int i; + float *pt; + + // Guess image size if not set completely. + nsvg__imageBounds(p, bounds); + + if (p->viewWidth == 0) { + if (p->image->width > 0) { + p->viewWidth = p->image->width; + } + else { + p->viewMinx = bounds[0]; + p->viewWidth = bounds[2] - bounds[0]; + } + } + if (p->viewHeight == 0) { + if (p->image->height > 0) { + p->viewHeight = p->image->height; + } + else { + p->viewMiny = bounds[1]; + p->viewHeight = bounds[3] - bounds[1]; + } + } + if (p->image->width == 0) + p->image->width = p->viewWidth; + if (p->image->height == 0) + p->image->height = p->viewHeight; + + tx = -p->viewMinx; + ty = -p->viewMiny; + sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0; + sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0; + // Unit scaling + us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f); + + // Fix aspect ratio + if (p->alignType == NSVG_ALIGN_MEET) { + // fit whole image into viewbox + sx = sy = nsvg__minf(sx, sy); + tx += nsvg__viewAlign(p->viewWidth * sx, p->image->width, p->alignX) / sx; + ty += nsvg__viewAlign(p->viewHeight * sy, p->image->height, p->alignY) / sy; + } + else if (p->alignType == NSVG_ALIGN_SLICE) { + // fill whole viewbox with image + sx = sy = nsvg__maxf(sx, sy); + tx += nsvg__viewAlign(p->viewWidth * sx, p->image->width, p->alignX) / sx; + ty += nsvg__viewAlign(p->viewHeight * sy, p->image->height, p->alignY) / sy; + } + + // Transform + sx *= us; + sy *= us; + avgs = (sx + sy) / 2.0f; + for (shape = p->image->shapes; shape != NULL; shape = shape->next) { + shape->bounds[0] = (shape->bounds[0] + tx) * sx; + shape->bounds[1] = (shape->bounds[1] + ty) * sy; + shape->bounds[2] = (shape->bounds[2] + tx) * sx; + shape->bounds[3] = (shape->bounds[3] + ty) * sy; + for (path = shape->paths; path != NULL; path = path->next) { + path->bounds[0] = (path->bounds[0] + tx) * sx; + path->bounds[1] = (path->bounds[1] + ty) * sy; + path->bounds[2] = (path->bounds[2] + tx) * sx; + path->bounds[3] = (path->bounds[3] + ty) * sy; + for (i = 0; i < path->npts; i++) { + pt = &path->pts[i * 2]; + pt[0] = (pt[0] + tx) * sx; + pt[1] = (pt[1] + ty) * sy; + } + } + + if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || + shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) { + nsvg__scaleGradient(shape->fill.gradient, tx, ty, sx, sy); + memcpy(t, shape->fill.gradient->xform, sizeof(float) * 6); + nsvg__xformInverse(shape->fill.gradient->xform, t); + } + if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || + shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) { + nsvg__scaleGradient(shape->stroke.gradient, tx, ty, sx, sy); + memcpy(t, shape->stroke.gradient->xform, sizeof(float) * 6); + nsvg__xformInverse(shape->stroke.gradient->xform, t); + } + + shape->strokeWidth *= avgs; + shape->strokeDashOffset *= avgs; + for (i = 0; i < shape->strokeDashCount; i++) + shape->strokeDashArray[i] *= avgs; + } +} + +NSVGimage *nsvgParse(char *input, const char *units, float dpi) +{ + NSVGparser *p; + NSVGimage *ret = 0; + + p = nsvg__createParser(); + if (p == NULL) { + return NULL; + } + p->dpi = dpi; + + nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p); + + // Scale to viewBox + nsvg__scaleToViewbox(p, units); + + ret = p->image; + p->image = NULL; + + nsvg__deleteParser(p); + + return ret; +} + +NSVGimage *nsvgParseFromFile(const char *filename, const char *units, float dpi) +{ + FILE *fp = NULL; + size_t size; + char *data = NULL; + NSVGimage *image = NULL; + + fp = fopen(filename, "rb"); + if (!fp) + goto error; + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + data = (char *)malloc(size + 1); + if (data == NULL) + goto error; + if (fread(data, 1, size, fp) != size) + goto error; + data[size] = '\0'; // Must be null terminated. + fclose(fp); + image = nsvgParse(data, units, dpi); + free(data); + + return image; + +error: + if (fp) + fclose(fp); + if (data) + free(data); + if (image) + nsvgDelete(image); + return NULL; +} + +NSVGpath *nsvgDuplicatePath(NSVGpath *p) +{ + NSVGpath *res = NULL; + + if (p == NULL) + return NULL; + + res = (NSVGpath *)malloc(sizeof(NSVGpath)); + if (res == NULL) + goto error; + memset(res, 0, sizeof(NSVGpath)); + + res->pts = (float *)malloc(p->npts * 2 * sizeof(float)); + if (res->pts == NULL) + goto error; + memcpy(res->pts, p->pts, p->npts * sizeof(float) * 2); + res->npts = p->npts; + + memcpy(res->bounds, p->bounds, sizeof(p->bounds)); + + res->closed = p->closed; + + return res; + +error: + if (res != NULL) { + free(res->pts); + free(res); + } + return NULL; +} + +void nsvgDelete(NSVGimage *image) +{ + NSVGshape *snext, *shape; + if (image == NULL) + return; + shape = image->shapes; + while (shape != NULL) { + snext = shape->next; + nsvg__deletePaths(shape->paths); + nsvg__deletePaint(&shape->fill); + nsvg__deletePaint(&shape->stroke); + free(shape); + shape = snext; + } + free(image); +} + +#endif diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 077f9bf8bdc..d88db091cc2 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -763,19 +763,53 @@ typedef enum IDRecalcFlag { * See e.g. how #BKE_library_unused_linked_data_set_tag is doing this. */ enum { + /* Special case: Library, should never ever depend on any other type. */ INDEX_ID_LI = 0, - INDEX_ID_IP, + + /* Animation types, might be used by almost all other types. */ + INDEX_ID_IP, /* Deprecated. */ INDEX_ID_AC, - INDEX_ID_KE, - INDEX_ID_PAL, + + /* Grease Pencil, special case, should be with the other obdata, but it can also be used by many + * other ID types, including node trees e.g. + * So there is no proper place for those, for now keep close to the lower end of the processing + * hierarchy, but we may want to re-evaluate that at some point. */ INDEX_ID_GD, + + /* Node trees, abstraction for procedural data, potentially used by many other ID types. + * + * NOTE: While node trees can also use many other ID types, they should not /own/ any of those, + * while they are being owned by many other ID types. This is why they are placed here. */ INDEX_ID_NT, + + /* File-wrapper types, those usually 'embed' external files in Blender, with no dependencies to + * other ID types. */ + INDEX_ID_VF, + INDEX_ID_TXT, + INDEX_ID_SO, + + /* Image/movie types, can be used by shading ID types, but also directly by Objects, Scenes, etc. + */ + INDEX_ID_MSK, INDEX_ID_IM, + INDEX_ID_MC, + + /* Shading types. */ INDEX_ID_TE, INDEX_ID_MA, - INDEX_ID_VF, - INDEX_ID_AR, + INDEX_ID_LS, + INDEX_ID_WO, + + /* Simulation-related types. */ INDEX_ID_CF, + INDEX_ID_SIM, + INDEX_ID_PA, + + /* Shape Keys snow-flake, can be used by several obdata types. */ + INDEX_ID_KE, + + /* Object data types. */ + INDEX_ID_AR, INDEX_ID_ME, INDEX_ID_CU, INDEX_ID_MB, @@ -785,26 +819,28 @@ enum { INDEX_ID_LT, INDEX_ID_LA, INDEX_ID_CA, - INDEX_ID_TXT, - INDEX_ID_SO, - INDEX_ID_GR, - INDEX_ID_PC, - INDEX_ID_BR, - INDEX_ID_PA, INDEX_ID_SPK, INDEX_ID_LP, - INDEX_ID_WO, - INDEX_ID_MC, - INDEX_ID_SCR, + + /* Collection and object types. */ INDEX_ID_OB, - INDEX_ID_LS, + INDEX_ID_GR, + + /* Preset-like, not-really-data types, can use many other ID types but should never be used by + * any actual data type (besides Scene, due to tool settings). */ + INDEX_ID_PAL, + INDEX_ID_PC, + INDEX_ID_BR, + + /* Scene, after preset-like ID types because of tool settings. */ INDEX_ID_SCE, + + /* UI-related types, should never be used by any other data type. */ + INDEX_ID_SCR, INDEX_ID_WS, INDEX_ID_WM, - /* TODO: This should probably be tweaked, #Mask and #Simulation are rather low-level types that - * should most likely be defined //before// #Object and geometry type indices? */ - INDEX_ID_MSK, - INDEX_ID_SIM, + + /* Special values. */ INDEX_ID_NULL, INDEX_ID_MAX, }; diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index b04fea11a4d..b53318cfbfe 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -160,6 +160,7 @@ const EnumPropertyItem rna_enum_object_gpencil_type_items[] = { {GP_EMPTY, "EMPTY", ICON_EMPTY_AXIS, "Blank", "Create an empty grease pencil object"}, {GP_STROKE, "STROKE", ICON_STROKE, "Stroke", "Create a simple stroke with basic colors"}, {GP_MONKEY, "MONKEY", ICON_MONKEY, "Monkey", "Construct a Suzanne grease pencil object"}, + {0, "", 0, NULL, NULL}, {GP_LRT_SCENE, "LRT_SCENE", ICON_SCENE_DATA, diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index d089894a6e9..c3611488f5f 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -22,6 +22,7 @@ */ #include <stddef.h> +#include <stdio.h> #include <string.h> #include "MEM_guardedalloc.h" diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index 72b05dcce70..e9228a2942b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -223,8 +223,10 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top, transform.values, true); + BMeshToMeshParams params{}; + params.calc_object_remap = false; Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr); - BM_mesh_bm_to_me_for_eval(bm, mesh, nullptr); + BM_mesh_bm_to_me(nullptr, bm, mesh, ¶ms); BM_mesh_free(bm); return mesh; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc index 1803a13f651..f8a9bfd2ed1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc @@ -50,8 +50,10 @@ static Mesh *create_cube_mesh(const float size) size, true); + BMeshToMeshParams params{}; + params.calc_object_remap = false; Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr); - BM_mesh_bm_to_me_for_eval(bm, mesh, nullptr); + BM_mesh_bm_to_me(nullptr, bm, mesh, ¶ms); BM_mesh_free(bm); return mesh; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc index f16b37fe977..242cc6ed7df 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc @@ -52,8 +52,10 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions, const float radius) transform.values, true); + BMeshToMeshParams params{}; + params.calc_object_remap = false; Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr); - BM_mesh_bm_to_me_for_eval(bm, mesh, nullptr); + BM_mesh_bm_to_me(nullptr, bm, mesh, ¶ms); BM_mesh_free(bm); return mesh; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index b7d249c18bc..8efba91da1a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -85,8 +85,10 @@ static Mesh *create_uv_sphere_mesh_bmesh(const float radius, const int segments, transform.values, true); + BMeshToMeshParams params{}; + params.calc_object_remap = false; Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr); - BM_mesh_bm_to_me_for_eval(bm, mesh, nullptr); + BM_mesh_bm_to_me(nullptr, bm, mesh, ¶ms); BM_mesh_free(bm); return mesh; diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 5fca6f4cec6..563a76ac824 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -3984,7 +3984,7 @@ PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele) case BM_LOOP: return BPy_BMLoop_CreatePyObject(bm, (BMLoop *)ele); default: - BLI_assert(0); + BLI_assert_unreachable(); PyErr_SetString(PyExc_SystemError, "internal error"); return NULL; } diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 471a311c411..78c43d18609 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -56,7 +56,7 @@ static CustomData *bpy_bm_customdata_get(BMesh *bm, char htype) return &bm->ldata; } - BLI_assert(0); + BLI_assert_unreachable(); return NULL; } @@ -958,7 +958,7 @@ PyObject *BPy_BMLayerAccess_CreatePyObject(BMesh *bm, const char htype) type = &BPy_BMLayerAccessLoop_Type; break; default: { - BLI_assert(0); + BLI_assert_unreachable(); type = NULL; break; } diff --git a/source/blender/python/generic/imbuf_py_api.c b/source/blender/python/generic/imbuf_py_api.c index 5b4a4fd237e..97a66bc23c0 100644 --- a/source/blender/python/generic/imbuf_py_api.c +++ b/source/blender/python/generic/imbuf_py_api.c @@ -123,7 +123,7 @@ static PyObject *py_imbuf_resize(Py_ImBuf *self, PyObject *args, PyObject *kw) IMB_scaleImBuf(self->ibuf, UNPACK2(size)); } else { - BLI_assert(0); + BLI_assert_unreachable(); } Py_RETURN_NONE; } diff --git a/source/blender/python/gpu/gpu_py_matrix.c b/source/blender/python/gpu/gpu_py_matrix.c index df7c82379b3..b00a13d5be8 100644 --- a/source/blender/python/gpu/gpu_py_matrix.c +++ b/source/blender/python/gpu/gpu_py_matrix.c @@ -201,7 +201,7 @@ static PyObject *pygpu_matrix_stack_context_enter(BPyGPU_MatrixStackContext *sel self->level = GPU_matrix_stack_level_get_projection(); } else { - BLI_assert(0); + BLI_assert_unreachable(); } Py_RETURN_NONE; } @@ -234,7 +234,7 @@ static PyObject *pygpu_matrix_stack_context_exit(BPyGPU_MatrixStackContext *self } } else { - BLI_assert(0); + BLI_assert_unreachable(); } finally: Py_RETURN_NONE; diff --git a/source/blender/python/gpu/gpu_py_vertex_buffer.c b/source/blender/python/gpu/gpu_py_vertex_buffer.c index 111fa114c43..3c7038186b9 100644 --- a/source/blender/python/gpu/gpu_py_vertex_buffer.c +++ b/source/blender/python/gpu/gpu_py_vertex_buffer.c @@ -70,7 +70,8 @@ break; \ } \ default: \ - BLI_assert(0); \ + BLI_assert_unreachable(); \ + break; \ } \ ((void)0) diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index c7816aed3c1..9ac8d4d9f47 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -363,4 +363,12 @@ if(WITH_POTRACE) add_definitions(-DWITH_POTRACE) endif() +if(WITH_PUGIXML) + add_definitions(-DWITH_PUGIXML) +endif() + +if(WITH_HARU) + add_definitions(-DWITH_HARU) +endif() + blender_add_lib(bf_python "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/python/intern/bpy_app_build_options.c b/source/blender/python/intern/bpy_app_build_options.c index 9f12c9f80f1..676d1b8045f 100644 --- a/source/blender/python/intern/bpy_app_build_options.c +++ b/source/blender/python/intern/bpy_app_build_options.c @@ -65,6 +65,8 @@ static PyStructSequence_Field app_builtopts_info_fields[] = { {"fluid", NULL}, {"xr_openxr", NULL}, {"potrace", NULL}, + {"pugixml", NULL}, + {"haru", NULL}, /* Sentinel (this line prevents `clang-format` wrapping into columns). */ {NULL}, }; @@ -311,6 +313,18 @@ static PyObject *make_builtopts_info(void) SetObjIncref(Py_False); #endif +#ifdef WITH_PUGIXML + SetObjIncref(Py_True); +#else + SetObjIncref(Py_False); +#endif + +#ifdef WITH_HARU + SetObjIncref(Py_True); +#else + SetObjIncref(Py_False); +#endif + #undef SetObjIncref return builtopts_info; diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index fab73d0f3dc..49ac2662a31 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1345,7 +1345,7 @@ BLI_bitmap *pyrna_set_to_enum_bitmap(const EnumPropertyItem *items, index = (int)ret_convert.as_unsigned; } else { - BLI_assert(0); + BLI_assert_unreachable(); } } BLI_assert(index < bitmap_size); @@ -5550,7 +5550,7 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self, case PROP_POINTER: case PROP_COLLECTION: /* Should never happen. */ - BLI_assert(false); + BLI_assert_unreachable(); break; } @@ -5595,7 +5595,7 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self, case PROP_POINTER: case PROP_COLLECTION: /* Should never happen. */ - BLI_assert(false); + BLI_assert_unreachable(); break; } diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 016ba462030..161d2f41592 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -1049,7 +1049,8 @@ static void adjoint_matrix_n(float *mat_dst, const float *mat_src, const ushort break; } default: - BLI_assert(0); + BLI_assert_unreachable(); + break; } } @@ -1159,7 +1160,7 @@ static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat) break; } default: - BLI_assert(0); + BLI_assert_unreachable(); } } diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c index 4db7350544b..cc11796496c 100644 --- a/source/blender/sequencer/intern/sequencer.c +++ b/source/blender/sequencer/intern/sequencer.c @@ -488,7 +488,7 @@ static Sequence *seq_dupli(const Scene *scene_src, } else { /* sequence type not handled in duplicate! Expect a crash now... */ - BLI_assert(0); + BLI_assert_unreachable(); } /* When using SEQ_DUPE_UNIQUE_NAME, it is mandatory to add new sequences in relevant container diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index 1e77ccd7a1c..32b6a6e6b31 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -324,7 +324,7 @@ bool wm_gizmogroup_is_visible_in_drawstep(const wmGizmoGroup *gzgroup, case WM_GIZMOMAP_DRAWSTEP_3D: return (gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D); default: - BLI_assert(0); + BLI_assert_unreachable(); return false; } } @@ -393,7 +393,7 @@ static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE return OPERATOR_FINISHED; } - BLI_assert(0); + BLI_assert_unreachable(); return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); } @@ -498,7 +498,7 @@ static int gizmo_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event) bool clear_modal = true; if (gz == NULL) { - BLI_assert(0); + BLI_assert_unreachable(); return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); } @@ -585,7 +585,7 @@ static int gizmo_tweak_invoke(bContext *C, wmOperator *op, const wmEvent *event) if (!gz) { /* wm_handlers_do_intern shouldn't let this happen */ - BLI_assert(0); + BLI_assert_unreachable(); return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); } diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c index a9e24867351..ab5a265547d 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c @@ -18,6 +18,8 @@ * \ingroup wm */ +#include <stdio.h> + #include "BLI_ghash.h" #include "BLI_utildefines.h" diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index 9b38f010205..45950a32d85 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -941,7 +941,7 @@ bool WM_gizmomap_select_all(bContext *C, wmGizmoMap *gzmap, const int action) changed = wm_gizmomap_deselect_all(gzmap); break; default: - BLI_assert(0); + BLI_assert_unreachable(); break; } diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c index efd7a13d02a..185854b1ca0 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c @@ -18,6 +18,8 @@ * \ingroup wm */ +#include <stdio.h> + #include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ed1b53e8e20..791aeeb39cd 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -144,7 +144,7 @@ wmEvent *wm_event_add(wmWindow *win, const wmEvent *event_to_add) wmEvent *WM_event_add_simulate(wmWindow *win, const wmEvent *event_to_add) { if ((G.f & G_FLAG_EVENT_SIMULATE) == 0) { - BLI_assert(0); + BLI_assert_unreachable(); return NULL; } wmEvent *event = wm_event_add(win, event_to_add); @@ -1037,7 +1037,7 @@ static void wm_operator_finished(bContext *C, wmOperator *op, const bool repeat, ED_area_type_hud_clear(wm, NULL); } else { - BLI_assert(0); + BLI_assert_unreachable(); } } } @@ -2885,7 +2885,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers } else { /* Unreachable (handle all types above). */ - BLI_assert(0); + BLI_assert_unreachable(); } if (action & WM_HANDLER_BREAK) { diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index a9b30f91bee..bbcb0669cce 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -2298,7 +2298,7 @@ static int operator_state_dispatch(bContext *C, wmOperator *op, OperatorDispatch return target.run(C, op); } } - BLI_assert(false); + BLI_assert_unreachable(); return OPERATOR_CANCELLED; } diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index bf7cf81f0a9..840debad01b 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -750,7 +750,7 @@ static void lib_relocate_do_remap(Main *bmain, /* In some cases, new_id might become direct link, remove parent of library in this case. */ if (new_id->lib->parent && (new_id->tag & LIB_TAG_INDIRECT) == 0) { if (do_reload) { - BLI_assert(0); /* Should not happen in 'pure' reload case... */ + BLI_assert_unreachable(); /* Should not happen in 'pure' reload case... */ } new_id->lib->parent = NULL; } diff --git a/source/blender/windowmanager/intern/wm_menu_type.c b/source/blender/windowmanager/intern/wm_menu_type.c index 0c52e636e4d..bcaa2243f9f 100644 --- a/source/blender/windowmanager/intern/wm_menu_type.c +++ b/source/blender/windowmanager/intern/wm_menu_type.c @@ -20,6 +20,8 @@ * Menu Registry. */ +#include <stdio.h> + #include "BLI_sys_types.h" #include "DNA_windowmanager_types.h" diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 07aaa5a800f..bc45f9486b3 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1229,7 +1229,7 @@ ID *WM_operator_drop_load_path(struct bContext *C, wmOperator *op, const short i id = (ID *)BKE_image_load_exists_ex(bmain, path, &exists); } else { - BLI_assert(0); + BLI_assert_unreachable(); } if (!id) { @@ -1248,7 +1248,7 @@ ID *WM_operator_drop_load_path(struct bContext *C, wmOperator *op, const short i BLI_path_rel(((Image *)id)->filepath, BKE_main_blendfile_path(bmain)); } else { - BLI_assert(0); + BLI_assert_unreachable(); } } } @@ -1687,7 +1687,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *region, void *userdat UI_but_func_menu_search(but); } else { - BLI_assert(0); + BLI_assert_unreachable(); } UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT); diff --git a/source/blender/windowmanager/intern/wm_uilist_type.c b/source/blender/windowmanager/intern/wm_uilist_type.c index ef6d855cb36..45c14c0bbe9 100644 --- a/source/blender/windowmanager/intern/wm_uilist_type.c +++ b/source/blender/windowmanager/intern/wm_uilist_type.c @@ -20,6 +20,8 @@ * UI List Registry. */ +#include <stdio.h> + #include "BLI_sys_types.h" #include "DNA_windowmanager_types.h" diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 25232e8e3d5..eb1da15807c 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -2174,7 +2174,7 @@ void WM_window_screen_rect_calc(const wmWindow *win, rcti *r_rect) screen_rect.ymin += height; break; default: - BLI_assert(0); + BLI_assert_unreachable(); break; } } |