diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/blenkernel/intern/gpencil.c | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/blenkernel/intern/gpencil.c')
-rw-r--r-- | source/blender/blenkernel/intern/gpencil.c | 2605 |
1 files changed, 1308 insertions, 1297 deletions
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index d47b3f20a28..d1181eeb03d 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -21,7 +21,6 @@ * \ingroup bke */ - #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -65,22 +64,22 @@ static CLG_LogRef LOG = {"bke.gpencil"}; /* ************************************************** */ /* Draw Engine */ -void(*BKE_gpencil_batch_cache_dirty_tag_cb)(bGPdata *gpd) = NULL; -void(*BKE_gpencil_batch_cache_free_cb)(bGPdata *gpd) = NULL; +void (*BKE_gpencil_batch_cache_dirty_tag_cb)(bGPdata *gpd) = NULL; +void (*BKE_gpencil_batch_cache_free_cb)(bGPdata *gpd) = NULL; void BKE_gpencil_batch_cache_dirty_tag(bGPdata *gpd) { - if (gpd) { - DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY); - BKE_gpencil_batch_cache_dirty_tag_cb(gpd); - } + if (gpd) { + DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY); + BKE_gpencil_batch_cache_dirty_tag_cb(gpd); + } } void BKE_gpencil_batch_cache_free(bGPdata *gpd) { - if (gpd) { - BKE_gpencil_batch_cache_free_cb(gpd); - } + if (gpd) { + BKE_gpencil_batch_cache_free_cb(gpd); + } } /* ************************************************** */ @@ -89,138 +88,138 @@ void BKE_gpencil_batch_cache_free(bGPdata *gpd) /* clean vertex groups weights */ void BKE_gpencil_free_point_weights(MDeformVert *dvert) { - if (dvert == NULL) { - return; - } - MEM_SAFE_FREE(dvert->dw); + if (dvert == NULL) { + return; + } + MEM_SAFE_FREE(dvert->dw); } void BKE_gpencil_free_stroke_weights(bGPDstroke *gps) { - if (gps == NULL) { - return; - } + if (gps == NULL) { + return; + } - if (gps->dvert == NULL) { - return; - } + if (gps->dvert == NULL) { + return; + } - for (int i = 0; i < gps->totpoints; i++) { - MDeformVert *dvert = &gps->dvert[i]; - BKE_gpencil_free_point_weights(dvert); - } + for (int i = 0; i < gps->totpoints; i++) { + MDeformVert *dvert = &gps->dvert[i]; + BKE_gpencil_free_point_weights(dvert); + } } /* free stroke, doesn't unlink from any listbase */ void BKE_gpencil_free_stroke(bGPDstroke *gps) { - if (gps == NULL) { - return; - } - /* free stroke memory arrays, then stroke itself */ - if (gps->points) { - MEM_freeN(gps->points); - } - if (gps->dvert) { - BKE_gpencil_free_stroke_weights(gps); - MEM_freeN(gps->dvert); - } - if (gps->triangles) - MEM_freeN(gps->triangles); + if (gps == NULL) { + return; + } + /* free stroke memory arrays, then stroke itself */ + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } + if (gps->triangles) + MEM_freeN(gps->triangles); - MEM_freeN(gps); + MEM_freeN(gps); } /* Free strokes belonging to a gp-frame */ bool BKE_gpencil_free_strokes(bGPDframe *gpf) { - bGPDstroke *gps_next; - bool changed = (BLI_listbase_is_empty(&gpf->strokes) == false); + bGPDstroke *gps_next; + bool changed = (BLI_listbase_is_empty(&gpf->strokes) == false); - /* free strokes */ - for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps_next) { - gps_next = gps->next; - BKE_gpencil_free_stroke(gps); - } - BLI_listbase_clear(&gpf->strokes); + /* free strokes */ + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps_next) { + gps_next = gps->next; + BKE_gpencil_free_stroke(gps); + } + BLI_listbase_clear(&gpf->strokes); - return changed; + return changed; } /* Free strokes and colors belonging to a gp-frame */ bool BKE_gpencil_free_frame_runtime_data(bGPDframe *derived_gpf) { - bGPDstroke *gps_next; - if (!derived_gpf) { - return false; - } + bGPDstroke *gps_next; + if (!derived_gpf) { + return false; + } - /* free strokes */ - for (bGPDstroke *gps = derived_gpf->strokes.first; gps; gps = gps_next) { - gps_next = gps->next; - BKE_gpencil_free_stroke(gps); - } - BLI_listbase_clear(&derived_gpf->strokes); + /* free strokes */ + for (bGPDstroke *gps = derived_gpf->strokes.first; gps; gps = gps_next) { + gps_next = gps->next; + BKE_gpencil_free_stroke(gps); + } + BLI_listbase_clear(&derived_gpf->strokes); - return true; + return true; } /* Free all of a gp-layer's frames */ void BKE_gpencil_free_frames(bGPDlayer *gpl) { - bGPDframe *gpf_next; + bGPDframe *gpf_next; - /* error checking */ - if (gpl == NULL) return; + /* error checking */ + if (gpl == NULL) + return; - /* free frames */ - for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf_next) { - gpf_next = gpf->next; + /* free frames */ + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf_next) { + gpf_next = gpf->next; - /* free strokes and their associated memory */ - BKE_gpencil_free_strokes(gpf); - BLI_freelinkN(&gpl->frames, gpf); - } - gpl->actframe = NULL; + /* free strokes and their associated memory */ + BKE_gpencil_free_strokes(gpf); + BLI_freelinkN(&gpl->frames, gpf); + } + gpl->actframe = NULL; } - - /* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */ void BKE_gpencil_free_layers(ListBase *list) { - bGPDlayer *gpl_next; + bGPDlayer *gpl_next; - /* error checking */ - if (list == NULL) return; + /* error checking */ + if (list == NULL) + return; - /* delete layers */ - for (bGPDlayer *gpl = list->first; gpl; gpl = gpl_next) { - gpl_next = gpl->next; + /* delete layers */ + for (bGPDlayer *gpl = list->first; gpl; gpl = gpl_next) { + gpl_next = gpl->next; - /* free layers and their data */ - BKE_gpencil_free_frames(gpl); - BLI_freelinkN(list, gpl); - } + /* free layers and their data */ + BKE_gpencil_free_frames(gpl); + BLI_freelinkN(list, gpl); + } } /** Free (or release) any data used by this grease pencil (does not free the gpencil itself). */ void BKE_gpencil_free(bGPdata *gpd, bool free_all) { - /* clear animation data */ - BKE_animdata_free(&gpd->id, false); + /* clear animation data */ + BKE_animdata_free(&gpd->id, false); - /* free layers */ - BKE_gpencil_free_layers(&gpd->layers); + /* free layers */ + BKE_gpencil_free_layers(&gpd->layers); - /* materials */ - MEM_SAFE_FREE(gpd->mat); + /* materials */ + MEM_SAFE_FREE(gpd->mat); - /* free all data */ - if (free_all) { - /* clear cache */ - BKE_gpencil_batch_cache_free(gpd); - } + /* free all data */ + if (free_all) { + /* clear cache */ + BKE_gpencil_batch_cache_free(gpd); + } } /* ************************************************** */ @@ -229,211 +228,211 @@ void BKE_gpencil_free(bGPdata *gpd, bool free_all) /* add a new gp-frame to the given layer */ bGPDframe *BKE_gpencil_frame_addnew(bGPDlayer *gpl, int cframe) { - bGPDframe *gpf = NULL, *gf = NULL; - short state = 0; - - /* error checking */ - if (gpl == NULL) - return NULL; - - /* allocate memory for this frame */ - gpf = MEM_callocN(sizeof(bGPDframe), "bGPDframe"); - gpf->framenum = cframe; - - /* find appropriate place to add frame */ - if (gpl->frames.first) { - for (gf = gpl->frames.first; gf; gf = gf->next) { - /* check if frame matches one that is supposed to be added */ - if (gf->framenum == cframe) { - state = -1; - break; - } - - /* if current frame has already exceeded the frame to add, add before */ - if (gf->framenum > cframe) { - BLI_insertlinkbefore(&gpl->frames, gf, gpf); - state = 1; - break; - } - } - } - - /* check whether frame was added successfully */ - if (state == -1) { - CLOG_ERROR(&LOG, "Frame (%d) existed already for this layer. Using existing frame", cframe); - - /* free the newly created one, and use the old one instead */ - MEM_freeN(gpf); - - /* return existing frame instead... */ - BLI_assert(gf != NULL); - gpf = gf; - } - else if (state == 0) { - /* add to end then! */ - BLI_addtail(&gpl->frames, gpf); - } - - /* return frame */ - return gpf; + bGPDframe *gpf = NULL, *gf = NULL; + short state = 0; + + /* error checking */ + if (gpl == NULL) + return NULL; + + /* allocate memory for this frame */ + gpf = MEM_callocN(sizeof(bGPDframe), "bGPDframe"); + gpf->framenum = cframe; + + /* find appropriate place to add frame */ + if (gpl->frames.first) { + for (gf = gpl->frames.first; gf; gf = gf->next) { + /* check if frame matches one that is supposed to be added */ + if (gf->framenum == cframe) { + state = -1; + break; + } + + /* if current frame has already exceeded the frame to add, add before */ + if (gf->framenum > cframe) { + BLI_insertlinkbefore(&gpl->frames, gf, gpf); + state = 1; + break; + } + } + } + + /* check whether frame was added successfully */ + if (state == -1) { + CLOG_ERROR(&LOG, "Frame (%d) existed already for this layer. Using existing frame", cframe); + + /* free the newly created one, and use the old one instead */ + MEM_freeN(gpf); + + /* return existing frame instead... */ + BLI_assert(gf != NULL); + gpf = gf; + } + else if (state == 0) { + /* add to end then! */ + BLI_addtail(&gpl->frames, gpf); + } + + /* return frame */ + return gpf; } /* add a copy of the active gp-frame to the given layer */ bGPDframe *BKE_gpencil_frame_addcopy(bGPDlayer *gpl, int cframe) { - bGPDframe *new_frame; - bool found = false; - - /* Error checking/handling */ - if (gpl == NULL) { - /* no layer */ - return NULL; - } - else if (gpl->actframe == NULL) { - /* no active frame, so just create a new one from scratch */ - return BKE_gpencil_frame_addnew(gpl, cframe); - } - - /* Create a copy of the frame */ - new_frame = BKE_gpencil_frame_duplicate(gpl->actframe); - - /* Find frame to insert it before */ - for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { - if (gpf->framenum > cframe) { - /* Add it here */ - BLI_insertlinkbefore(&gpl->frames, gpf, new_frame); - - found = true; - break; - } - else if (gpf->framenum == cframe) { - /* This only happens when we're editing with framelock on... - * - Delete the new frame and don't do anything else here... - */ - BKE_gpencil_free_strokes(new_frame); - MEM_freeN(new_frame); - new_frame = NULL; - - found = true; - break; - } - } - - if (found == false) { - /* Add new frame to the end */ - BLI_addtail(&gpl->frames, new_frame); - } - - /* Ensure that frame is set up correctly, and return it */ - if (new_frame) { - new_frame->framenum = cframe; - gpl->actframe = new_frame; - } - - return new_frame; + bGPDframe *new_frame; + bool found = false; + + /* Error checking/handling */ + if (gpl == NULL) { + /* no layer */ + return NULL; + } + else if (gpl->actframe == NULL) { + /* no active frame, so just create a new one from scratch */ + return BKE_gpencil_frame_addnew(gpl, cframe); + } + + /* Create a copy of the frame */ + new_frame = BKE_gpencil_frame_duplicate(gpl->actframe); + + /* Find frame to insert it before */ + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + if (gpf->framenum > cframe) { + /* Add it here */ + BLI_insertlinkbefore(&gpl->frames, gpf, new_frame); + + found = true; + break; + } + else if (gpf->framenum == cframe) { + /* This only happens when we're editing with framelock on... + * - Delete the new frame and don't do anything else here... + */ + BKE_gpencil_free_strokes(new_frame); + MEM_freeN(new_frame); + new_frame = NULL; + + found = true; + break; + } + } + + if (found == false) { + /* Add new frame to the end */ + BLI_addtail(&gpl->frames, new_frame); + } + + /* Ensure that frame is set up correctly, and return it */ + if (new_frame) { + new_frame->framenum = cframe; + gpl->actframe = new_frame; + } + + return new_frame; } /* add a new gp-layer and make it the active layer */ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setactive) { - bGPDlayer *gpl = NULL; - bGPDlayer *gpl_active = NULL; - - /* check that list is ok */ - if (gpd == NULL) - return NULL; - - /* allocate memory for frame and add to end of list */ - gpl = MEM_callocN(sizeof(bGPDlayer), "bGPDlayer"); - - gpl_active = BKE_gpencil_layer_getactive(gpd); - - /* add to datablock */ - if (gpl_active == NULL) { - BLI_addtail(&gpd->layers, gpl); - } - else { - /* if active layer, add after that layer */ - BLI_insertlinkafter(&gpd->layers, gpl_active, gpl); - } - - /* annotation vs GP Object behavior is slightly different */ - if (gpd->flag & GP_DATA_ANNOTATIONS) { - /* set default color of new strokes for this layer */ - copy_v4_v4(gpl->color, U.gpencil_new_layer_col); - gpl->opacity = 1.0f; - - /* set default thickness of new strokes for this layer */ - gpl->thickness = 3; - - /* Onion colors */ - ARRAY_SET_ITEMS(gpl->gcolor_prev, 0.302f, 0.851f, 0.302f); - ARRAY_SET_ITEMS(gpl->gcolor_next, 0.250f, 0.1f, 1.0f); - } - else { - /* thickness parameter represents "thickness change", not absolute thickness */ - gpl->thickness = 0; - gpl->opacity = 1.0f; - /* default channel color */ - ARRAY_SET_ITEMS(gpl->color, 0.2f, 0.2f, 0.2f); - } - - /* auto-name */ - BLI_strncpy(gpl->info, name, sizeof(gpl->info)); - BLI_uniquename(&gpd->layers, gpl, - (gpd->flag & GP_DATA_ANNOTATIONS) ? DATA_("Note") : DATA_("GP_Layer"), - '.', - offsetof(bGPDlayer, info), - sizeof(gpl->info)); - - /* make this one the active one */ - if (setactive) - BKE_gpencil_layer_setactive(gpd, gpl); - - /* return layer */ - return gpl; + bGPDlayer *gpl = NULL; + bGPDlayer *gpl_active = NULL; + + /* check that list is ok */ + if (gpd == NULL) + return NULL; + + /* allocate memory for frame and add to end of list */ + gpl = MEM_callocN(sizeof(bGPDlayer), "bGPDlayer"); + + gpl_active = BKE_gpencil_layer_getactive(gpd); + + /* add to datablock */ + if (gpl_active == NULL) { + BLI_addtail(&gpd->layers, gpl); + } + else { + /* if active layer, add after that layer */ + BLI_insertlinkafter(&gpd->layers, gpl_active, gpl); + } + + /* annotation vs GP Object behavior is slightly different */ + if (gpd->flag & GP_DATA_ANNOTATIONS) { + /* set default color of new strokes for this layer */ + copy_v4_v4(gpl->color, U.gpencil_new_layer_col); + gpl->opacity = 1.0f; + + /* set default thickness of new strokes for this layer */ + gpl->thickness = 3; + + /* Onion colors */ + ARRAY_SET_ITEMS(gpl->gcolor_prev, 0.302f, 0.851f, 0.302f); + ARRAY_SET_ITEMS(gpl->gcolor_next, 0.250f, 0.1f, 1.0f); + } + else { + /* thickness parameter represents "thickness change", not absolute thickness */ + gpl->thickness = 0; + gpl->opacity = 1.0f; + /* default channel color */ + ARRAY_SET_ITEMS(gpl->color, 0.2f, 0.2f, 0.2f); + } + + /* auto-name */ + BLI_strncpy(gpl->info, name, sizeof(gpl->info)); + BLI_uniquename(&gpd->layers, + gpl, + (gpd->flag & GP_DATA_ANNOTATIONS) ? DATA_("Note") : DATA_("GP_Layer"), + '.', + offsetof(bGPDlayer, info), + sizeof(gpl->info)); + + /* make this one the active one */ + if (setactive) + BKE_gpencil_layer_setactive(gpd, gpl); + + /* return layer */ + return gpl; } /* add a new gp-datablock */ bGPdata *BKE_gpencil_data_addnew(Main *bmain, const char name[]) { - bGPdata *gpd; + bGPdata *gpd; - /* allocate memory for a new block */ - gpd = BKE_libblock_alloc(bmain, ID_GD, name, 0); + /* allocate memory for a new block */ + gpd = BKE_libblock_alloc(bmain, ID_GD, name, 0); - /* initial settings */ - gpd->flag = (GP_DATA_DISPINFO | GP_DATA_EXPAND); + /* initial settings */ + gpd->flag = (GP_DATA_DISPINFO | GP_DATA_EXPAND); - /* general flags */ - gpd->flag |= GP_DATA_VIEWALIGN; - gpd->flag |= GP_DATA_STROKE_FORCE_RECALC; - /* always enable object onion skin swith */ - gpd->flag |= GP_DATA_SHOW_ONIONSKINS; - /* GP object specific settings */ - ARRAY_SET_ITEMS(gpd->line_color, 0.6f, 0.6f, 0.6f, 0.5f); + /* general flags */ + gpd->flag |= GP_DATA_VIEWALIGN; + gpd->flag |= GP_DATA_STROKE_FORCE_RECALC; + /* always enable object onion skin swith */ + gpd->flag |= GP_DATA_SHOW_ONIONSKINS; + /* GP object specific settings */ + ARRAY_SET_ITEMS(gpd->line_color, 0.6f, 0.6f, 0.6f, 0.5f); - gpd->pixfactor = GP_DEFAULT_PIX_FACTOR; + gpd->pixfactor = GP_DEFAULT_PIX_FACTOR; - /* grid settings */ - ARRAY_SET_ITEMS(gpd->grid.color, 0.5f, 0.5f, 0.5f); // Color - ARRAY_SET_ITEMS(gpd->grid.scale, 1.0f, 1.0f); // Scale - gpd->grid.lines = GP_DEFAULT_GRID_LINES; // Number of lines + /* grid settings */ + ARRAY_SET_ITEMS(gpd->grid.color, 0.5f, 0.5f, 0.5f); // Color + ARRAY_SET_ITEMS(gpd->grid.scale, 1.0f, 1.0f); // Scale + gpd->grid.lines = GP_DEFAULT_GRID_LINES; // Number of lines - /* onion-skinning settings (datablock level) */ - gpd->onion_flag |= (GP_ONION_GHOST_PREVCOL | GP_ONION_GHOST_NEXTCOL); - gpd->onion_flag |= GP_ONION_FADE; - gpd->onion_mode = GP_ONION_MODE_RELATIVE; - gpd->onion_factor = 0.5f; - ARRAY_SET_ITEMS(gpd->gcolor_prev, 0.145098f, 0.419608f, 0.137255f); /* green */ - ARRAY_SET_ITEMS(gpd->gcolor_next, 0.125490f, 0.082353f, 0.529412f); /* blue */ - gpd->gstep = 1; - gpd->gstep_next = 1; + /* onion-skinning settings (datablock level) */ + gpd->onion_flag |= (GP_ONION_GHOST_PREVCOL | GP_ONION_GHOST_NEXTCOL); + gpd->onion_flag |= GP_ONION_FADE; + gpd->onion_mode = GP_ONION_MODE_RELATIVE; + gpd->onion_factor = 0.5f; + ARRAY_SET_ITEMS(gpd->gcolor_prev, 0.145098f, 0.419608f, 0.137255f); /* green */ + ARRAY_SET_ITEMS(gpd->gcolor_next, 0.125490f, 0.082353f, 0.529412f); /* blue */ + gpd->gstep = 1; + gpd->gstep_next = 1; - return gpd; + return gpd; } - /* ************************************************** */ /* Primitive Creation */ /* Utilities for easier bulk-creation of geometry */ @@ -444,173 +443,175 @@ bGPdata *BKE_gpencil_data_addnew(Main *bmain, const char name[]) * \param array: Flat array of point data values. Each entry has GP_PRIM_DATABUF_SIZE values * \param mat: 4x4 transform matrix to transform points into the right coordinate space */ -void BKE_gpencil_stroke_add_points(bGPDstroke *gps, const float *array, const int totpoints, const float mat[4][4]) +void BKE_gpencil_stroke_add_points(bGPDstroke *gps, + const float *array, + const int totpoints, + const float mat[4][4]) { - for (int i = 0; i < totpoints; i++) { - bGPDspoint *pt = &gps->points[i]; - const int x = GP_PRIM_DATABUF_SIZE * i; + for (int i = 0; i < totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + const int x = GP_PRIM_DATABUF_SIZE * i; - pt->x = array[x]; - pt->y = array[x + 1]; - pt->z = array[x + 2]; - mul_m4_v3(mat, &pt->x); + pt->x = array[x]; + pt->y = array[x + 1]; + pt->z = array[x + 2]; + mul_m4_v3(mat, &pt->x); - pt->pressure = array[x + 3]; - pt->strength = array[x + 4]; - } + pt->pressure = array[x + 3]; + pt->strength = array[x + 4]; + } } /* Create a new stroke, with pre-allocated data buffers */ bGPDstroke *BKE_gpencil_add_stroke(bGPDframe *gpf, int mat_idx, int totpoints, short thickness) { - /* allocate memory for a new stroke */ - bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); + /* allocate memory for a new stroke */ + bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); - gps->thickness = thickness; - gps->gradient_f = 1.0f; - gps->gradient_s[0] = 1.0f; - gps->gradient_s[1] = 1.0f; + gps->thickness = thickness; + gps->gradient_f = 1.0f; + gps->gradient_s[0] = 1.0f; + gps->gradient_s[1] = 1.0f; - gps->inittime = 0; + gps->inittime = 0; - /* enable recalculation flag by default */ - gps->flag = GP_STROKE_RECALC_GEOMETRY | GP_STROKE_3DSPACE; + /* enable recalculation flag by default */ + gps->flag = GP_STROKE_RECALC_GEOMETRY | GP_STROKE_3DSPACE; - gps->totpoints = totpoints; - gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + gps->totpoints = totpoints; + gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); - /* initialize triangle memory to dummy data */ - gps->triangles = MEM_callocN(sizeof(bGPDtriangle), "GP Stroke triangulation"); - gps->flag |= GP_STROKE_RECALC_GEOMETRY; - gps->tot_triangles = 0; + /* initialize triangle memory to dummy data */ + gps->triangles = MEM_callocN(sizeof(bGPDtriangle), "GP Stroke triangulation"); + gps->flag |= GP_STROKE_RECALC_GEOMETRY; + gps->tot_triangles = 0; - gps->mat_nr = mat_idx; + gps->mat_nr = mat_idx; - /* add to frame */ - BLI_addtail(&gpf->strokes, gps); + /* add to frame */ + BLI_addtail(&gpf->strokes, gps); - return gps; + return gps; } - /* ************************************************** */ /* Data Duplication */ /* make a copy of a given gpencil weights */ void BKE_gpencil_stroke_weights_duplicate(bGPDstroke *gps_src, bGPDstroke *gps_dst) { - if (gps_src == NULL) { - return; - } - BLI_assert(gps_src->totpoints == gps_dst->totpoints); + if (gps_src == NULL) { + return; + } + BLI_assert(gps_src->totpoints == gps_dst->totpoints); - BKE_defvert_array_copy(gps_dst->dvert, gps_src->dvert, gps_src->totpoints); + BKE_defvert_array_copy(gps_dst->dvert, gps_src->dvert, gps_src->totpoints); } /* make a copy of a given gpencil stroke */ bGPDstroke *BKE_gpencil_stroke_duplicate(bGPDstroke *gps_src) { - bGPDstroke *gps_dst = NULL; + bGPDstroke *gps_dst = NULL; - gps_dst = MEM_dupallocN(gps_src); - gps_dst->prev = gps_dst->next = NULL; + gps_dst = MEM_dupallocN(gps_src); + gps_dst->prev = gps_dst->next = NULL; - gps_dst->points = MEM_dupallocN(gps_src->points); + gps_dst->points = MEM_dupallocN(gps_src->points); - if (gps_src->dvert != NULL) { - gps_dst->dvert = MEM_dupallocN(gps_src->dvert); - BKE_gpencil_stroke_weights_duplicate(gps_src, gps_dst); - } - else { - gps_dst->dvert = NULL; - } + if (gps_src->dvert != NULL) { + gps_dst->dvert = MEM_dupallocN(gps_src->dvert); + BKE_gpencil_stroke_weights_duplicate(gps_src, gps_dst); + } + else { + gps_dst->dvert = NULL; + } - /* Don't clear triangles, so that modifier evaluation can just use - * this without extra work first. Most places that need to force - * this data to get recalculated will destroy the data anyway though. - */ - gps_dst->triangles = MEM_dupallocN(gps_dst->triangles); - /* gps_dst->flag |= GP_STROKE_RECALC_GEOMETRY; */ + /* Don't clear triangles, so that modifier evaluation can just use + * this without extra work first. Most places that need to force + * this data to get recalculated will destroy the data anyway though. + */ + gps_dst->triangles = MEM_dupallocN(gps_dst->triangles); + /* gps_dst->flag |= GP_STROKE_RECALC_GEOMETRY; */ - /* return new stroke */ - return gps_dst; + /* return new stroke */ + return gps_dst; } /* make a copy of a given gpencil frame */ bGPDframe *BKE_gpencil_frame_duplicate(const bGPDframe *gpf_src) { - bGPDstroke *gps_dst = NULL; - bGPDframe *gpf_dst; + bGPDstroke *gps_dst = NULL; + bGPDframe *gpf_dst; - /* error checking */ - if (gpf_src == NULL) { - return NULL; - } + /* error checking */ + if (gpf_src == NULL) { + return NULL; + } - /* make a copy of the source frame */ - gpf_dst = MEM_dupallocN(gpf_src); - gpf_dst->prev = gpf_dst->next = NULL; + /* make a copy of the source frame */ + gpf_dst = MEM_dupallocN(gpf_src); + gpf_dst->prev = gpf_dst->next = NULL; - /* copy strokes */ - BLI_listbase_clear(&gpf_dst->strokes); - for (bGPDstroke *gps_src = gpf_src->strokes.first; gps_src; gps_src = gps_src->next) { - /* make copy of source stroke */ - gps_dst = BKE_gpencil_stroke_duplicate(gps_src); - BLI_addtail(&gpf_dst->strokes, gps_dst); - } + /* copy strokes */ + BLI_listbase_clear(&gpf_dst->strokes); + for (bGPDstroke *gps_src = gpf_src->strokes.first; gps_src; gps_src = gps_src->next) { + /* make copy of source stroke */ + gps_dst = BKE_gpencil_stroke_duplicate(gps_src); + BLI_addtail(&gpf_dst->strokes, gps_dst); + } - /* return new frame */ - return gpf_dst; + /* return new frame */ + return gpf_dst; } /* make a copy of strokes between gpencil frames */ void BKE_gpencil_frame_copy_strokes(bGPDframe *gpf_src, struct bGPDframe *gpf_dst) { - bGPDstroke *gps_dst = NULL; - /* error checking */ - if ((gpf_src == NULL) || (gpf_dst == NULL)) { - return; - } + bGPDstroke *gps_dst = NULL; + /* error checking */ + if ((gpf_src == NULL) || (gpf_dst == NULL)) { + return; + } - /* copy strokes */ - BLI_listbase_clear(&gpf_dst->strokes); - for (bGPDstroke *gps_src = gpf_src->strokes.first; gps_src; gps_src = gps_src->next) { - /* make copy of source stroke */ - gps_dst = BKE_gpencil_stroke_duplicate(gps_src); - BLI_addtail(&gpf_dst->strokes, gps_dst); - } + /* copy strokes */ + BLI_listbase_clear(&gpf_dst->strokes); + for (bGPDstroke *gps_src = gpf_src->strokes.first; gps_src; gps_src = gps_src->next) { + /* make copy of source stroke */ + gps_dst = BKE_gpencil_stroke_duplicate(gps_src); + BLI_addtail(&gpf_dst->strokes, gps_dst); + } } /* make a copy of a given gpencil layer */ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src) { - const bGPDframe *gpf_src; - bGPDframe *gpf_dst; - bGPDlayer *gpl_dst; + const bGPDframe *gpf_src; + bGPDframe *gpf_dst; + bGPDlayer *gpl_dst; - /* error checking */ - if (gpl_src == NULL) { - return NULL; - } + /* error checking */ + if (gpl_src == NULL) { + return NULL; + } - /* make a copy of source layer */ - gpl_dst = MEM_dupallocN(gpl_src); - gpl_dst->prev = gpl_dst->next = NULL; + /* make a copy of source layer */ + gpl_dst = MEM_dupallocN(gpl_src); + gpl_dst->prev = gpl_dst->next = NULL; - /* copy frames */ - BLI_listbase_clear(&gpl_dst->frames); - for (gpf_src = gpl_src->frames.first; gpf_src; gpf_src = gpf_src->next) { - /* make a copy of source frame */ - gpf_dst = BKE_gpencil_frame_duplicate(gpf_src); - BLI_addtail(&gpl_dst->frames, gpf_dst); + /* copy frames */ + BLI_listbase_clear(&gpl_dst->frames); + for (gpf_src = gpl_src->frames.first; gpf_src; gpf_src = gpf_src->next) { + /* make a copy of source frame */ + gpf_dst = BKE_gpencil_frame_duplicate(gpf_src); + BLI_addtail(&gpl_dst->frames, gpf_dst); - /* if source frame was the current layer's 'active' frame, reassign that too */ - if (gpf_src == gpl_dst->actframe) - gpl_dst->actframe = gpf_dst; - } + /* if source frame was the current layer's 'active' frame, reassign that too */ + if (gpf_src == gpl_dst->actframe) + gpl_dst->actframe = gpf_dst; + } - /* return new layer */ - return gpl_dst; + /* return new layer */ + return gpl_dst; } /** @@ -623,63 +624,63 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src) */ void BKE_gpencil_copy_data(bGPdata *gpd_dst, const bGPdata *gpd_src, const int UNUSED(flag)) { - /* duplicate material array */ - if (gpd_src->mat) { - gpd_dst->mat = MEM_dupallocN(gpd_src->mat); - } - - /* copy layers */ - BLI_listbase_clear(&gpd_dst->layers); - for (const bGPDlayer *gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) { - /* make a copy of source layer and its data */ - bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src); /* TODO here too could add unused flags... */ - BLI_addtail(&gpd_dst->layers, gpl_dst); - } + /* duplicate material array */ + if (gpd_src->mat) { + gpd_dst->mat = MEM_dupallocN(gpd_src->mat); + } + /* copy layers */ + BLI_listbase_clear(&gpd_dst->layers); + for (const bGPDlayer *gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) { + /* make a copy of source layer and its data */ + bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate( + gpl_src); /* TODO here too could add unused flags... */ + BLI_addtail(&gpd_dst->layers, gpl_dst); + } } /* Standard API to make a copy of GP datablock, separate from copying its data */ bGPdata *BKE_gpencil_copy(Main *bmain, const bGPdata *gpd) { - bGPdata *gpd_copy; - BKE_id_copy(bmain, &gpd->id, (ID **)&gpd_copy); - return gpd_copy; + bGPdata *gpd_copy; + BKE_id_copy(bmain, &gpd->id, (ID **)&gpd_copy); + return gpd_copy; } /* make a copy of a given gpencil datablock */ // XXX: Should this be deprecated? bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy) { - bGPdata *gpd_dst; + bGPdata *gpd_dst; - /* Yuck and super-uber-hyper yuck!!! - * Should be replaceable with a no-main copy (LIB_ID_COPY_NO_MAIN etc.), but not sure about it, - * so for now keep old code for that one. */ + /* Yuck and super-uber-hyper yuck!!! + * Should be replaceable with a no-main copy (LIB_ID_COPY_NO_MAIN etc.), but not sure about it, + * so for now keep old code for that one. */ - /* error checking */ - if (gpd_src == NULL) { - return NULL; - } + /* error checking */ + if (gpd_src == NULL) { + return NULL; + } - if (internal_copy) { - /* make a straight copy for undo buffers used during stroke drawing */ - gpd_dst = MEM_dupallocN(gpd_src); - } - else { - BLI_assert(bmain != NULL); - BKE_id_copy(bmain, &gpd_src->id, (ID **)&gpd_dst); - } + if (internal_copy) { + /* make a straight copy for undo buffers used during stroke drawing */ + gpd_dst = MEM_dupallocN(gpd_src); + } + else { + BLI_assert(bmain != NULL); + BKE_id_copy(bmain, &gpd_src->id, (ID **)&gpd_dst); + } - /* Copy internal data (layers, etc.) */ - BKE_gpencil_copy_data(gpd_dst, gpd_src, 0); + /* Copy internal data (layers, etc.) */ + BKE_gpencil_copy_data(gpd_dst, gpd_src, 0); - /* return new */ - return gpd_dst; + /* return new */ + return gpd_dst; } void BKE_gpencil_make_local(Main *bmain, bGPdata *gpd, const bool lib_local) { - BKE_id_make_local_generic(bmain, &gpd->id, true, lib_local); + BKE_id_make_local_generic(bmain, &gpd->id, true, lib_local); } /* ************************************************** */ @@ -688,24 +689,24 @@ void BKE_gpencil_make_local(Main *bmain, bGPdata *gpd, const bool lib_local) /* ensure selection status of stroke is in sync with its points */ void BKE_gpencil_stroke_sync_selection(bGPDstroke *gps) { - bGPDspoint *pt; - int i; + bGPDspoint *pt; + int i; - /* error checking */ - if (gps == NULL) - return; + /* error checking */ + if (gps == NULL) + return; - /* we'll stop when we find the first selected point, - * so initially, we must deselect - */ - gps->flag &= ~GP_STROKE_SELECT; + /* we'll stop when we find the first selected point, + * so initially, we must deselect + */ + gps->flag &= ~GP_STROKE_SELECT; - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) { - gps->flag |= GP_STROKE_SELECT; - break; - } - } + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + gps->flag |= GP_STROKE_SELECT; + break; + } + } } /* ************************************************** */ @@ -714,29 +715,29 @@ void BKE_gpencil_stroke_sync_selection(bGPDstroke *gps) /* delete the last stroke of the given frame */ void BKE_gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf) { - bGPDstroke *gps = (gpf) ? gpf->strokes.last : NULL; - int cfra = (gpf) ? gpf->framenum : 0; /* assume that the current frame was not locked */ + bGPDstroke *gps = (gpf) ? gpf->strokes.last : NULL; + int cfra = (gpf) ? gpf->framenum : 0; /* assume that the current frame was not locked */ - /* error checking */ - if (ELEM(NULL, gpf, gps)) - return; + /* error checking */ + if (ELEM(NULL, gpf, gps)) + return; - /* free the stroke and its data */ - if (gps->points) { - MEM_freeN(gps->points); - } - if (gps->dvert) { - BKE_gpencil_free_stroke_weights(gps); - MEM_freeN(gps->dvert); - } - MEM_freeN(gps->triangles); - BLI_freelinkN(&gpf->strokes, gps); + /* free the stroke and its data */ + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } + MEM_freeN(gps->triangles); + BLI_freelinkN(&gpf->strokes, gps); - /* if frame has no strokes after this, delete it */ - if (BLI_listbase_is_empty(&gpf->strokes)) { - BKE_gpencil_layer_delframe(gpl, gpf); - BKE_gpencil_layer_getframe(gpl, cfra, GP_GETFRAME_USE_PREV); - } + /* if frame has no strokes after this, delete it */ + if (BLI_listbase_is_empty(&gpf->strokes)) { + BKE_gpencil_layer_delframe(gpl, gpf); + BKE_gpencil_layer_getframe(gpl, cfra, GP_GETFRAME_USE_PREV); + } } /* ************************************************** */ @@ -745,39 +746,39 @@ void BKE_gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf) /* Check if the given layer is able to be edited or not */ bool gpencil_layer_is_editable(const bGPDlayer *gpl) { - /* Sanity check */ - if (gpl == NULL) - return false; + /* Sanity check */ + if (gpl == NULL) + return false; - /* Layer must be: Visible + Editable */ - if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0) { - /* Opacity must be sufficiently high that it is still "visible" - * Otherwise, it's not really "visible" to the user, so no point editing... - */ - if (gpl->opacity > GPENCIL_ALPHA_OPACITY_THRESH) { - return true; - } - } + /* Layer must be: Visible + Editable */ + if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0) { + /* Opacity must be sufficiently high that it is still "visible" + * Otherwise, it's not really "visible" to the user, so no point editing... + */ + if (gpl->opacity > GPENCIL_ALPHA_OPACITY_THRESH) { + return true; + } + } - /* Something failed */ - return false; + /* Something failed */ + return false; } /* Look up the gp-frame on the requested frame number, but don't add a new one */ bGPDframe *BKE_gpencil_layer_find_frame(bGPDlayer *gpl, int cframe) { - bGPDframe *gpf; + bGPDframe *gpf; - /* Search in reverse order, since this is often used for playback/adding, - * where it's less likely that we're interested in the earlier frames - */ - for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) { - if (gpf->framenum == cframe) { - return gpf; - } - } + /* Search in reverse order, since this is often used for playback/adding, + * where it's less likely that we're interested in the earlier frames + */ + for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) { + if (gpf->framenum == cframe) { + return gpf; + } + } - return NULL; + return NULL; } /* get the appropriate gp-frame from a given layer @@ -786,270 +787,270 @@ bGPDframe *BKE_gpencil_layer_find_frame(bGPDlayer *gpl, int cframe) */ bGPDframe *BKE_gpencil_layer_getframe(bGPDlayer *gpl, int cframe, eGP_GetFrame_Mode addnew) { - bGPDframe *gpf = NULL; - short found = 0; - - /* error checking */ - if (gpl == NULL) return NULL; - - /* check if there is already an active frame */ - if (gpl->actframe) { - gpf = gpl->actframe; - - /* do not allow any changes to layer's active frame if layer is locked from changes - * or if the layer has been set to stay on the current frame - */ - if (gpl->flag & GP_LAYER_FRAMELOCK) - return gpf; - /* do not allow any changes to actframe if frame has painting tag attached to it */ - if (gpf->flag & GP_FRAME_PAINT) - return gpf; - - /* try to find matching frame */ - if (gpf->framenum < cframe) { - for (; gpf; gpf = gpf->next) { - if (gpf->framenum == cframe) { - found = 1; - break; - } - else if ((gpf->next) && (gpf->next->framenum > cframe)) { - found = 1; - break; - } - } - - /* set the appropriate frame */ - if (addnew) { - if ((found) && (gpf->framenum == cframe)) - gpl->actframe = gpf; - else if (addnew == GP_GETFRAME_ADD_COPY) - gpl->actframe = BKE_gpencil_frame_addcopy(gpl, cframe); - else - gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe); - } - else if (found) - gpl->actframe = gpf; - else - gpl->actframe = gpl->frames.last; - } - else { - for (; gpf; gpf = gpf->prev) { - if (gpf->framenum <= cframe) { - found = 1; - break; - } - } - - /* set the appropriate frame */ - if (addnew) { - if ((found) && (gpf->framenum == cframe)) - gpl->actframe = gpf; - else if (addnew == GP_GETFRAME_ADD_COPY) - gpl->actframe = BKE_gpencil_frame_addcopy(gpl, cframe); - else - gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe); - } - else if (found) - gpl->actframe = gpf; - else - gpl->actframe = gpl->frames.first; - } - } - else if (gpl->frames.first) { - /* check which of the ends to start checking from */ - const int first = ((bGPDframe *)(gpl->frames.first))->framenum; - const int last = ((bGPDframe *)(gpl->frames.last))->framenum; - - if (abs(cframe - first) > abs(cframe - last)) { - /* find gp-frame which is less than or equal to cframe */ - for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) { - if (gpf->framenum <= cframe) { - found = 1; - break; - } - } - } - else { - /* find gp-frame which is less than or equal to cframe */ - for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { - if (gpf->framenum <= cframe) { - found = 1; - break; - } - } - } - - /* set the appropriate frame */ - if (addnew) { - if ((found) && (gpf->framenum == cframe)) - gpl->actframe = gpf; - else - gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe); - } - else if (found) - gpl->actframe = gpf; - else { - /* unresolved errogenous situation! */ - CLOG_STR_ERROR(&LOG, "cannot find appropriate gp-frame"); - /* gpl->actframe should still be NULL */ - } - } - else { - /* currently no frames (add if allowed to) */ - if (addnew) - gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe); - else { - /* don't do anything... this may be when no frames yet! */ - /* gpl->actframe should still be NULL */ - } - } - - /* return */ - return gpl->actframe; + bGPDframe *gpf = NULL; + short found = 0; + + /* error checking */ + if (gpl == NULL) + return NULL; + + /* check if there is already an active frame */ + if (gpl->actframe) { + gpf = gpl->actframe; + + /* do not allow any changes to layer's active frame if layer is locked from changes + * or if the layer has been set to stay on the current frame + */ + if (gpl->flag & GP_LAYER_FRAMELOCK) + return gpf; + /* do not allow any changes to actframe if frame has painting tag attached to it */ + if (gpf->flag & GP_FRAME_PAINT) + return gpf; + + /* try to find matching frame */ + if (gpf->framenum < cframe) { + for (; gpf; gpf = gpf->next) { + if (gpf->framenum == cframe) { + found = 1; + break; + } + else if ((gpf->next) && (gpf->next->framenum > cframe)) { + found = 1; + break; + } + } + + /* set the appropriate frame */ + if (addnew) { + if ((found) && (gpf->framenum == cframe)) + gpl->actframe = gpf; + else if (addnew == GP_GETFRAME_ADD_COPY) + gpl->actframe = BKE_gpencil_frame_addcopy(gpl, cframe); + else + gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe); + } + else if (found) + gpl->actframe = gpf; + else + gpl->actframe = gpl->frames.last; + } + else { + for (; gpf; gpf = gpf->prev) { + if (gpf->framenum <= cframe) { + found = 1; + break; + } + } + + /* set the appropriate frame */ + if (addnew) { + if ((found) && (gpf->framenum == cframe)) + gpl->actframe = gpf; + else if (addnew == GP_GETFRAME_ADD_COPY) + gpl->actframe = BKE_gpencil_frame_addcopy(gpl, cframe); + else + gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe); + } + else if (found) + gpl->actframe = gpf; + else + gpl->actframe = gpl->frames.first; + } + } + else if (gpl->frames.first) { + /* check which of the ends to start checking from */ + const int first = ((bGPDframe *)(gpl->frames.first))->framenum; + const int last = ((bGPDframe *)(gpl->frames.last))->framenum; + + if (abs(cframe - first) > abs(cframe - last)) { + /* find gp-frame which is less than or equal to cframe */ + for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) { + if (gpf->framenum <= cframe) { + found = 1; + break; + } + } + } + else { + /* find gp-frame which is less than or equal to cframe */ + for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { + if (gpf->framenum <= cframe) { + found = 1; + break; + } + } + } + + /* set the appropriate frame */ + if (addnew) { + if ((found) && (gpf->framenum == cframe)) + gpl->actframe = gpf; + else + gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe); + } + else if (found) + gpl->actframe = gpf; + else { + /* unresolved errogenous situation! */ + CLOG_STR_ERROR(&LOG, "cannot find appropriate gp-frame"); + /* gpl->actframe should still be NULL */ + } + } + else { + /* currently no frames (add if allowed to) */ + if (addnew) + gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe); + else { + /* don't do anything... this may be when no frames yet! */ + /* gpl->actframe should still be NULL */ + } + } + + /* return */ + return gpl->actframe; } /* delete the given frame from a layer */ bool BKE_gpencil_layer_delframe(bGPDlayer *gpl, bGPDframe *gpf) { - bool changed = false; + bool changed = false; - /* error checking */ - if (ELEM(NULL, gpl, gpf)) - return false; + /* error checking */ + if (ELEM(NULL, gpl, gpf)) + return false; - /* if this frame was active, make the previous frame active instead - * since it's tricky to set active frame otherwise - */ - if (gpl->actframe == gpf) - gpl->actframe = gpf->prev; + /* if this frame was active, make the previous frame active instead + * since it's tricky to set active frame otherwise + */ + if (gpl->actframe == gpf) + gpl->actframe = gpf->prev; - /* free the frame and its data */ - changed = BKE_gpencil_free_strokes(gpf); - BLI_freelinkN(&gpl->frames, gpf); + /* free the frame and its data */ + changed = BKE_gpencil_free_strokes(gpf); + BLI_freelinkN(&gpl->frames, gpf); - return changed; + return changed; } /* get the active gp-layer for editing */ bGPDlayer *BKE_gpencil_layer_getactive(bGPdata *gpd) { - bGPDlayer *gpl; + bGPDlayer *gpl; - /* error checking */ - if (ELEM(NULL, gpd, gpd->layers.first)) - return NULL; + /* error checking */ + if (ELEM(NULL, gpd, gpd->layers.first)) + return NULL; - /* loop over layers until found (assume only one active) */ - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - if (gpl->flag & GP_LAYER_ACTIVE) - return gpl; - } + /* loop over layers until found (assume only one active) */ + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if (gpl->flag & GP_LAYER_ACTIVE) + return gpl; + } - /* no active layer found */ - return NULL; + /* no active layer found */ + return NULL; } /* set the active gp-layer */ void BKE_gpencil_layer_setactive(bGPdata *gpd, bGPDlayer *active) { - bGPDlayer *gpl; + bGPDlayer *gpl; - /* error checking */ - if (ELEM(NULL, gpd, gpd->layers.first, active)) - return; + /* error checking */ + if (ELEM(NULL, gpd, gpd->layers.first, active)) + return; - /* loop over layers deactivating all */ - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - gpl->flag &= ~GP_LAYER_ACTIVE; - if (gpd->flag & GP_DATA_AUTOLOCK_LAYERS) { - gpl->flag |= GP_LAYER_LOCKED; - } - } + /* loop over layers deactivating all */ + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + gpl->flag &= ~GP_LAYER_ACTIVE; + if (gpd->flag & GP_DATA_AUTOLOCK_LAYERS) { + gpl->flag |= GP_LAYER_LOCKED; + } + } - /* set as active one */ - active->flag |= GP_LAYER_ACTIVE; - if (gpd->flag & GP_DATA_AUTOLOCK_LAYERS) { - active->flag &= ~GP_LAYER_LOCKED; - } + /* set as active one */ + active->flag |= GP_LAYER_ACTIVE; + if (gpd->flag & GP_DATA_AUTOLOCK_LAYERS) { + active->flag &= ~GP_LAYER_LOCKED; + } } /* delete the active gp-layer */ void BKE_gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl) { - /* error checking */ - if (ELEM(NULL, gpd, gpl)) - return; + /* error checking */ + if (ELEM(NULL, gpd, gpl)) + return; - /* free layer */ - BKE_gpencil_free_frames(gpl); + /* free layer */ + BKE_gpencil_free_frames(gpl); - /* free icon providing preview of icon color */ - BKE_icon_delete(gpl->runtime.icon_id); + /* free icon providing preview of icon color */ + BKE_icon_delete(gpl->runtime.icon_id); - BLI_freelinkN(&gpd->layers, gpl); + BLI_freelinkN(&gpd->layers, gpl); } Material *BKE_gpencil_brush_material_get(Brush *brush) { - Material *ma = NULL; + Material *ma = NULL; - if ((brush != NULL) && (brush->gpencil_settings != NULL) && - (brush->gpencil_settings->material != NULL)) - { - ma = brush->gpencil_settings->material; - } + if ((brush != NULL) && (brush->gpencil_settings != NULL) && + (brush->gpencil_settings->material != NULL)) { + ma = brush->gpencil_settings->material; + } - return ma; + return ma; } void BKE_gpencil_brush_material_set(Brush *brush, Material *ma) { - BLI_assert(brush); - BLI_assert(brush->gpencil_settings); - if (brush->gpencil_settings->material != ma) { - if (brush->gpencil_settings->material) { - id_us_min(&brush->gpencil_settings->material->id); - } - if (ma) { - id_us_plus(&ma->id); - } - brush->gpencil_settings->material = ma; - } + BLI_assert(brush); + BLI_assert(brush->gpencil_settings); + if (brush->gpencil_settings->material != ma) { + if (brush->gpencil_settings->material) { + id_us_min(&brush->gpencil_settings->material->id); + } + if (ma) { + id_us_plus(&ma->id); + } + brush->gpencil_settings->material = ma; + } } /* Adds the pinned material to the object if necessary. */ Material *BKE_gpencil_object_material_ensure_from_brush(Main *bmain, Object *ob, Brush *brush) { - if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) { - Material *ma = BKE_gpencil_brush_material_get(brush); + if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) { + Material *ma = BKE_gpencil_brush_material_get(brush); - /* check if the material is already on object material slots and add it if missing */ - if (ma && BKE_gpencil_object_material_get_index(ob, ma) < 0) { - BKE_object_material_slot_add(bmain, ob); - assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF); - } + /* check if the material is already on object material slots and add it if missing */ + if (ma && BKE_gpencil_object_material_get_index(ob, ma) < 0) { + BKE_object_material_slot_add(bmain, ob); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF); + } - return ma; - } - else { - /* using active material instead */ - return give_current_material(ob, ob->actcol); - } + return ma; + } + else { + /* using active material instead */ + return give_current_material(ob, ob->actcol); + } } /* Assigns the material to object (if not already present) and returns its index (mat_nr). */ int BKE_gpencil_object_material_ensure(Main *bmain, Object *ob, Material *material) { - if (!material) { - return -1; - } - int index = BKE_gpencil_object_material_get_index(ob, material); - if (index < 0) { - BKE_object_material_slot_add(bmain, ob); - assign_material(bmain, ob, material, ob->totcol, BKE_MAT_ASSIGN_USERPREF); - return ob->totcol - 1; - } - return index; + if (!material) { + return -1; + } + int index = BKE_gpencil_object_material_get_index(ob, material); + if (index < 0) { + BKE_object_material_slot_add(bmain, ob); + assign_material(bmain, ob, material, ob->totcol, BKE_MAT_ASSIGN_USERPREF); + return ob->totcol - 1; + } + return index; } /** Creates a new gpencil material and assigns it to object. @@ -1058,93 +1059,98 @@ int BKE_gpencil_object_material_ensure(Main *bmain, Object *ob, Material *materi */ Material *BKE_gpencil_object_material_new(Main *bmain, Object *ob, const char *name, int *r_index) { - Material *ma = BKE_material_add_gpencil(bmain, name); - id_us_min(&ma->id); /* no users yet */ + Material *ma = BKE_material_add_gpencil(bmain, name); + id_us_min(&ma->id); /* no users yet */ - BKE_object_material_slot_add(bmain, ob); - assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF); + BKE_object_material_slot_add(bmain, ob); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF); - if (r_index) { - *r_index = ob->actcol - 1; - } - return ma; + if (r_index) { + *r_index = ob->actcol - 1; + } + return ma; } /* Returns the material for a brush with respect to its pinned state. */ Material *BKE_gpencil_object_material_get_from_brush(Object *ob, Brush *brush) { - if ((brush) && (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) { - Material *ma = BKE_gpencil_brush_material_get(brush); - return ma; - } - else { - return give_current_material(ob, ob->actcol); - } + if ((brush) && (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) { + Material *ma = BKE_gpencil_brush_material_get(brush); + return ma; + } + else { + return give_current_material(ob, ob->actcol); + } } /* Returns the material index for a brush with respect to its pinned state. */ int BKE_gpencil_object_material_get_index_from_brush(Object *ob, Brush *brush) { - if ((brush) && (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) { - return BKE_gpencil_object_material_get_index(ob, brush->gpencil_settings->material); - } - else { - return ob->actcol - 1; - } + if ((brush) && (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) { + return BKE_gpencil_object_material_get_index(ob, brush->gpencil_settings->material); + } + else { + return ob->actcol - 1; + } } /* Guaranteed to return a material assigned to object. Returns never NULL. */ -Material *BKE_gpencil_object_material_ensure_from_active_input_toolsettings(Main *bmain, Object *ob, ToolSettings *ts) +Material *BKE_gpencil_object_material_ensure_from_active_input_toolsettings(Main *bmain, + Object *ob, + ToolSettings *ts) { - if (ts && ts->gp_paint && ts->gp_paint->paint.brush) { - return BKE_gpencil_object_material_ensure_from_active_input_brush(bmain, ob, ts->gp_paint->paint.brush); - } - else { - return BKE_gpencil_object_material_ensure_from_active_input_brush(bmain, ob, NULL); - } + if (ts && ts->gp_paint && ts->gp_paint->paint.brush) { + return BKE_gpencil_object_material_ensure_from_active_input_brush( + bmain, ob, ts->gp_paint->paint.brush); + } + else { + return BKE_gpencil_object_material_ensure_from_active_input_brush(bmain, ob, NULL); + } } /* Guaranteed to return a material assigned to object. Returns never NULL. */ -Material *BKE_gpencil_object_material_ensure_from_active_input_brush(Main *bmain, Object *ob, Brush *brush) -{ - if (brush) { - Material *ma = BKE_gpencil_object_material_ensure_from_brush(bmain, ob, brush); - if (ma) { - return ma; - } - else if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) { - /* it is easier to just unpin a NULL material, instead of setting a new one */ - brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED; - } - } - return BKE_gpencil_object_material_ensure_from_active_input_material(bmain, ob); +Material *BKE_gpencil_object_material_ensure_from_active_input_brush(Main *bmain, + Object *ob, + Brush *brush) +{ + if (brush) { + Material *ma = BKE_gpencil_object_material_ensure_from_brush(bmain, ob, brush); + if (ma) { + return ma; + } + else if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) { + /* it is easier to just unpin a NULL material, instead of setting a new one */ + brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED; + } + } + return BKE_gpencil_object_material_ensure_from_active_input_material(bmain, ob); } /* Guaranteed to return a material assigned to object. Returns never NULL. Only use this for materials unrelated to user input */ Material *BKE_gpencil_object_material_ensure_from_active_input_material(Main *bmain, Object *ob) { - Material *ma = give_current_material(ob, ob->actcol); - if (ma) { - return ma; - } - return BKE_gpencil_object_material_new(bmain, ob, "Material", NULL); + Material *ma = give_current_material(ob, ob->actcol); + if (ma) { + return ma; + } + return BKE_gpencil_object_material_new(bmain, ob, "Material", NULL); } /* Get active color, and add all default settings if we don't find anything */ Material *BKE_gpencil_object_material_ensure_active(Main *bmain, Object *ob) { - Material *ma = NULL; + Material *ma = NULL; - /* sanity checks */ - if (ELEM(NULL, bmain, ob)) - return NULL; + /* sanity checks */ + if (ELEM(NULL, bmain, ob)) + return NULL; - ma = BKE_gpencil_object_material_ensure_from_active_input_material(bmain, ob); - if (ma->gp_style == NULL) { - BKE_material_init_gpencil_settings(ma); - } + ma = BKE_gpencil_object_material_ensure_from_active_input_material(bmain, ob); + if (ma->gp_style == NULL) { + BKE_material_init_gpencil_settings(ma); + } - return ma; + return ma; } /* ************************************************** */ @@ -1154,112 +1160,111 @@ Material *BKE_gpencil_object_material_ensure_active(Main *bmain, Object *ob) * Get min/max coordinate bounds for single stroke * \return Returns whether we found any selected points */ -bool BKE_gpencil_stroke_minmax( - const bGPDstroke *gps, const bool use_select, - float r_min[3], float r_max[3]) +bool BKE_gpencil_stroke_minmax(const bGPDstroke *gps, + const bool use_select, + float r_min[3], + float r_max[3]) { - const bGPDspoint *pt; - int i; - bool changed = false; + const bGPDspoint *pt; + int i; + bool changed = false; - if (ELEM(NULL, gps, r_min, r_max)) - return false; + if (ELEM(NULL, gps, r_min, r_max)) + return false; - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if ((use_select == false) || (pt->flag & GP_SPOINT_SELECT)) { - minmax_v3v3_v3(r_min, r_max, &pt->x); - changed = true; - } - } - return changed; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if ((use_select == false) || (pt->flag & GP_SPOINT_SELECT)) { + minmax_v3v3_v3(r_min, r_max, &pt->x); + changed = true; + } + } + return changed; } /* get min/max bounds of all strokes in GP datablock */ bool BKE_gpencil_data_minmax(const bGPdata *gpd, float r_min[3], float r_max[3]) { - bool changed = false; + bool changed = false; - INIT_MINMAX(r_min, r_max); + INIT_MINMAX(r_min, r_max); - if (gpd == NULL) - return changed; + if (gpd == NULL) + return changed; - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - bGPDframe *gpf = gpl->actframe; + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + bGPDframe *gpf = gpl->actframe; - if (gpf != NULL) { - for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { - changed = BKE_gpencil_stroke_minmax(gps, false, r_min, r_max); - } - } - } + if (gpf != NULL) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + changed = BKE_gpencil_stroke_minmax(gps, false, r_min, r_max); + } + } + } - return changed; + return changed; } -bool BKE_gpencil_stroke_select_check( - const bGPDstroke *gps) +bool BKE_gpencil_stroke_select_check(const bGPDstroke *gps) { - const bGPDspoint *pt; - int i; - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) { - return true; - } - } - return false; + const bGPDspoint *pt; + int i; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + return true; + } + } + return false; } /* compute center of bounding box */ void BKE_gpencil_centroid_3d(bGPdata *gpd, float r_centroid[3]) { - float min[3], max[3], tot[3]; + float min[3], max[3], tot[3]; - BKE_gpencil_data_minmax(gpd, min, max); + BKE_gpencil_data_minmax(gpd, min, max); - add_v3_v3v3(tot, min, max); - mul_v3_v3fl(r_centroid, tot, 0.5f); + add_v3_v3v3(tot, min, max); + mul_v3_v3fl(r_centroid, tot, 0.5f); } - /* create bounding box values */ static void boundbox_gpencil(Object *ob) { - BoundBox *bb; - bGPdata *gpd; - float min[3], max[3]; + BoundBox *bb; + bGPdata *gpd; + float min[3], max[3]; - if (ob->runtime.bb == NULL) { - ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "GPencil boundbox"); - } + if (ob->runtime.bb == NULL) { + ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "GPencil boundbox"); + } - bb = ob->runtime.bb; - gpd = ob->data; + bb = ob->runtime.bb; + gpd = ob->data; - if (!BKE_gpencil_data_minmax(gpd, min, max)) { - min[0] = min[1] = min[2] = -1.0f; - max[0] = max[1] = max[2] = 1.0f; - } + if (!BKE_gpencil_data_minmax(gpd, min, max)) { + min[0] = min[1] = min[2] = -1.0f; + max[0] = max[1] = max[2] = 1.0f; + } - BKE_boundbox_init_from_minmax(bb, min, max); + BKE_boundbox_init_from_minmax(bb, min, max); - bb->flag &= ~BOUNDBOX_DIRTY; + bb->flag &= ~BOUNDBOX_DIRTY; } /* get bounding box */ BoundBox *BKE_gpencil_boundbox_get(Object *ob) { - if (ELEM(NULL, ob, ob->data)) - return NULL; + if (ELEM(NULL, ob, ob->data)) + return NULL; - bGPdata *gpd = (bGPdata *)ob->data; - if ((ob->runtime.bb) && ((gpd->flag & GP_DATA_CACHE_IS_DIRTY) == 0)) { - return ob->runtime.bb; - } + bGPdata *gpd = (bGPdata *)ob->data; + if ((ob->runtime.bb) && ((gpd->flag & GP_DATA_CACHE_IS_DIRTY) == 0)) { + return ob->runtime.bb; + } - boundbox_gpencil(ob); + boundbox_gpencil(ob); - return ob->runtime.bb; + return ob->runtime.bb; } /* ************************************************** */ @@ -1267,34 +1272,33 @@ BoundBox *BKE_gpencil_boundbox_get(Object *ob) void BKE_gpencil_transform(bGPdata *gpd, float mat[4][4]) { - if (gpd == NULL) - return; - - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - /* FIXME: For now, we just skip parented layers. - * Otherwise, we have to update each frame to find - * the current parent position/effects. - */ - if (gpl->parent) { - continue; - } + if (gpd == NULL) + return; - for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { - for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { - bGPDspoint *pt; - int i; + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* FIXME: For now, we just skip parented layers. + * Otherwise, we have to update each frame to find + * the current parent position/effects. + */ + if (gpl->parent) { + continue; + } - for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) { - mul_m4_v3(mat, &pt->x); - } + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + bGPDspoint *pt; + int i; - /* TODO: Do we need to do this? distortion may mean we need to re-triangulate */ - gps->flag |= GP_STROKE_RECALC_GEOMETRY; - gps->tot_triangles = 0; - } - } - } + for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) { + mul_m4_v3(mat, &pt->x); + } + /* TODO: Do we need to do this? distortion may mean we need to re-triangulate */ + gps->flag |= GP_STROKE_RECALC_GEOMETRY; + gps->tot_triangles = 0; + } + } + } } /* ************************************************** */ @@ -1303,49 +1307,48 @@ void BKE_gpencil_transform(bGPdata *gpd, float mat[4][4]) /* remove a vertex group */ void BKE_gpencil_vgroup_remove(Object *ob, bDeformGroup *defgroup) { - bGPdata *gpd = ob->data; - MDeformVert *dvert = NULL; - const int def_nr = BLI_findindex(&ob->defbase, defgroup); - - /* Remove points data */ - if (gpd) { - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { - for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { - if (gps->dvert != NULL) { - for (int i = 0; i < gps->totpoints; i++) { - dvert = &gps->dvert[i]; - MDeformWeight *dw = defvert_find_index(dvert, def_nr); - if (dw != NULL) { - defvert_remove_group(dvert, dw); - } - else { - /* reorganize weights in other strokes */ - for (int g = 0; g < gps->dvert->totweight; g++) { - dw = &dvert->dw[g]; - if ((dw != NULL) && (dw->def_nr > def_nr)) { - dw->def_nr--; - } - } - } - } - } - } - } - } - } - - /* Remove the group */ - BLI_freelinkN(&ob->defbase, defgroup); - DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + bGPdata *gpd = ob->data; + MDeformVert *dvert = NULL; + const int def_nr = BLI_findindex(&ob->defbase, defgroup); + + /* Remove points data */ + if (gpd) { + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + if (gps->dvert != NULL) { + for (int i = 0; i < gps->totpoints; i++) { + dvert = &gps->dvert[i]; + MDeformWeight *dw = defvert_find_index(dvert, def_nr); + if (dw != NULL) { + defvert_remove_group(dvert, dw); + } + else { + /* reorganize weights in other strokes */ + for (int g = 0; g < gps->dvert->totweight; g++) { + dw = &dvert->dw[g]; + if ((dw != NULL) && (dw->def_nr > def_nr)) { + dw->def_nr--; + } + } + } + } + } + } + } + } + } + + /* Remove the group */ + BLI_freelinkN(&ob->defbase, defgroup); + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); } - void BKE_gpencil_dvert_ensure(bGPDstroke *gps) { - if (gps->dvert == NULL) { - gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); - } + if (gps->dvert == NULL) { + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); + } } /* ************************************************** */ @@ -1358,134 +1361,133 @@ void BKE_gpencil_dvert_ensure(bGPDstroke *gps) */ bool BKE_gpencil_smooth_stroke(bGPDstroke *gps, int i, float inf) { - bGPDspoint *pt = &gps->points[i]; - // float pressure = 0.0f; - float sco[3] = { 0.0f }; + bGPDspoint *pt = &gps->points[i]; + // float pressure = 0.0f; + float sco[3] = {0.0f}; - /* Do nothing if not enough points to smooth out */ - if (gps->totpoints <= 2) { - return false; - } + /* Do nothing if not enough points to smooth out */ + if (gps->totpoints <= 2) { + return false; + } - /* Only affect endpoints by a fraction of the normal strength, - * to prevent the stroke from shrinking too much - */ - if ((i == 0) || (i == gps->totpoints - 1)) { - inf *= 0.1f; - } + /* Only affect endpoints by a fraction of the normal strength, + * to prevent the stroke from shrinking too much + */ + if ((i == 0) || (i == gps->totpoints - 1)) { + inf *= 0.1f; + } - /* Compute smoothed coordinate by taking the ones nearby */ - /* XXX: This is potentially slow, and suffers from accumulation error as earlier points are handled before later ones */ - { - // XXX: this is hardcoded to look at 2 points on either side of the current one (i.e. 5 items total) - const int steps = 2; - const float average_fac = 1.0f / (float)(steps * 2 + 1); - int step; + /* Compute smoothed coordinate by taking the ones nearby */ + /* XXX: This is potentially slow, and suffers from accumulation error as earlier points are handled before later ones */ + { + // XXX: this is hardcoded to look at 2 points on either side of the current one (i.e. 5 items total) + const int steps = 2; + const float average_fac = 1.0f / (float)(steps * 2 + 1); + int step; - /* add the point itself */ - madd_v3_v3fl(sco, &pt->x, average_fac); + /* add the point itself */ + madd_v3_v3fl(sco, &pt->x, average_fac); - /* n-steps before/after current point */ - // XXX: review how the endpoints are treated by this algorithm - // XXX: falloff measures should also introduce some weighting variations, so that further-out points get less weight - for (step = 1; step <= steps; step++) { - bGPDspoint *pt1, *pt2; - int before = i - step; - int after = i + step; + /* n-steps before/after current point */ + // XXX: review how the endpoints are treated by this algorithm + // XXX: falloff measures should also introduce some weighting variations, so that further-out points get less weight + for (step = 1; step <= steps; step++) { + bGPDspoint *pt1, *pt2; + int before = i - step; + int after = i + step; - CLAMP_MIN(before, 0); - CLAMP_MAX(after, gps->totpoints - 1); + CLAMP_MIN(before, 0); + CLAMP_MAX(after, gps->totpoints - 1); - pt1 = &gps->points[before]; - pt2 = &gps->points[after]; + pt1 = &gps->points[before]; + pt2 = &gps->points[after]; - /* add both these points to the average-sum (s += p[i]/n) */ - madd_v3_v3fl(sco, &pt1->x, average_fac); - madd_v3_v3fl(sco, &pt2->x, average_fac); + /* add both these points to the average-sum (s += p[i]/n) */ + madd_v3_v3fl(sco, &pt1->x, average_fac); + madd_v3_v3fl(sco, &pt2->x, average_fac); + } + } - } - } + /* Based on influence factor, blend between original and optimal smoothed coordinate */ + interp_v3_v3v3(&pt->x, &pt->x, sco, inf); - /* Based on influence factor, blend between original and optimal smoothed coordinate */ - interp_v3_v3v3(&pt->x, &pt->x, sco, inf); - - return true; + return true; } /** * Apply smooth for strength to stroke point */ bool BKE_gpencil_smooth_stroke_strength(bGPDstroke *gps, int point_index, float influence) { - bGPDspoint *ptb = &gps->points[point_index]; + bGPDspoint *ptb = &gps->points[point_index]; - /* Do nothing if not enough points */ - if (gps->totpoints <= 2) { - return false; - } + /* Do nothing if not enough points */ + if (gps->totpoints <= 2) { + return false; + } - /* Compute theoretical optimal value using distances */ - bGPDspoint *pta, *ptc; - int before = point_index - 1; - int after = point_index + 1; + /* Compute theoretical optimal value using distances */ + bGPDspoint *pta, *ptc; + int before = point_index - 1; + int after = point_index + 1; - CLAMP_MIN(before, 0); - CLAMP_MAX(after, gps->totpoints - 1); + CLAMP_MIN(before, 0); + CLAMP_MAX(after, gps->totpoints - 1); - pta = &gps->points[before]; - ptc = &gps->points[after]; + pta = &gps->points[before]; + ptc = &gps->points[after]; - /* the optimal value is the corresponding to the interpolation of the strength - * at the distance of point b - */ - float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); - /* sometimes the factor can be wrong due stroke geometry, so use middle point */ - if ((fac < 0.0f) || (fac > 1.0f)) { - fac = 0.5f; - } - const float optimal = (1.0f - fac) * pta->strength + fac * ptc->strength; + /* the optimal value is the corresponding to the interpolation of the strength + * at the distance of point b + */ + float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); + /* sometimes the factor can be wrong due stroke geometry, so use middle point */ + if ((fac < 0.0f) || (fac > 1.0f)) { + fac = 0.5f; + } + const float optimal = (1.0f - fac) * pta->strength + fac * ptc->strength; - /* Based on influence factor, blend between original and optimal */ - ptb->strength = (1.0f - influence) * ptb->strength + influence * optimal; + /* Based on influence factor, blend between original and optimal */ + ptb->strength = (1.0f - influence) * ptb->strength + influence * optimal; - return true; + return true; } /** * Apply smooth for thickness to stroke point (use pressure) */ bool BKE_gpencil_smooth_stroke_thickness(bGPDstroke *gps, int point_index, float influence) { - bGPDspoint *ptb = &gps->points[point_index]; + bGPDspoint *ptb = &gps->points[point_index]; - /* Do nothing if not enough points */ - if ((gps->totpoints <= 2) || (point_index < 1)) { - return false; - } + /* Do nothing if not enough points */ + if ((gps->totpoints <= 2) || (point_index < 1)) { + return false; + } - /* Compute theoretical optimal value using distances */ - bGPDspoint *pta, *ptc; - int before = point_index - 1; - int after = point_index + 1; + /* Compute theoretical optimal value using distances */ + bGPDspoint *pta, *ptc; + int before = point_index - 1; + int after = point_index + 1; - CLAMP_MIN(before, 0); - CLAMP_MAX(after, gps->totpoints - 1); + CLAMP_MIN(before, 0); + CLAMP_MAX(after, gps->totpoints - 1); - pta = &gps->points[before]; - ptc = &gps->points[after]; + pta = &gps->points[before]; + ptc = &gps->points[after]; - /* the optimal value is the corresponding to the interpolation of the pressure - * at the distance of point b - */ - float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); - /* sometimes the factor can be wrong due stroke geometry, so use middle point */ - if ((fac < 0.0f) || (fac > 1.0f)) { - fac = 0.5f; - } - float optimal = interpf(ptc->pressure, pta->pressure, fac); + /* the optimal value is the corresponding to the interpolation of the pressure + * at the distance of point b + */ + float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); + /* sometimes the factor can be wrong due stroke geometry, so use middle point */ + if ((fac < 0.0f) || (fac > 1.0f)) { + fac = 0.5f; + } + float optimal = interpf(ptc->pressure, pta->pressure, fac); - /* Based on influence factor, blend between original and optimal */ - ptb->pressure = interpf(optimal, ptb->pressure, influence); + /* Based on influence factor, blend between original and optimal */ + ptb->pressure = interpf(optimal, ptb->pressure, influence); - return true; + return true; } /** @@ -1493,39 +1495,39 @@ bool BKE_gpencil_smooth_stroke_thickness(bGPDstroke *gps, int point_index, float */ bool BKE_gpencil_smooth_stroke_uv(bGPDstroke *gps, int point_index, float influence) { - bGPDspoint *ptb = &gps->points[point_index]; + bGPDspoint *ptb = &gps->points[point_index]; - /* Do nothing if not enough points */ - if (gps->totpoints <= 2) { - return false; - } + /* Do nothing if not enough points */ + if (gps->totpoints <= 2) { + return false; + } - /* Compute theoretical optimal value */ - bGPDspoint *pta, *ptc; - int before = point_index - 1; - int after = point_index + 1; + /* Compute theoretical optimal value */ + bGPDspoint *pta, *ptc; + int before = point_index - 1; + int after = point_index + 1; - CLAMP_MIN(before, 0); - CLAMP_MAX(after, gps->totpoints - 1); + CLAMP_MIN(before, 0); + CLAMP_MAX(after, gps->totpoints - 1); - pta = &gps->points[before]; - ptc = &gps->points[after]; + pta = &gps->points[before]; + ptc = &gps->points[after]; - /* the optimal value is the corresponding to the interpolation of the pressure - * at the distance of point b - */ - float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); - /* sometimes the factor can be wrong due stroke geometry, so use middle point */ - if ((fac < 0.0f) || (fac > 1.0f)) { - fac = 0.5f; - } - float optimal = interpf(ptc->uv_rot, pta->uv_rot, fac); + /* the optimal value is the corresponding to the interpolation of the pressure + * at the distance of point b + */ + float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); + /* sometimes the factor can be wrong due stroke geometry, so use middle point */ + if ((fac < 0.0f) || (fac > 1.0f)) { + fac = 0.5f; + } + float optimal = interpf(ptc->uv_rot, pta->uv_rot, fac); - /* Based on influence factor, blend between original and optimal */ - ptb->uv_rot = interpf(optimal, ptb->uv_rot, influence); - CLAMP(ptb->uv_rot, -M_PI_2, M_PI_2); + /* Based on influence factor, blend between original and optimal */ + ptb->uv_rot = interpf(optimal, ptb->uv_rot, influence); + CLAMP(ptb->uv_rot, -M_PI_2, M_PI_2); - return true; + return true; } /** @@ -1538,19 +1540,19 @@ bool BKE_gpencil_smooth_stroke_uv(bGPDstroke *gps, int point_index, float influe */ void BKE_gpencil_get_range_selected(bGPDlayer *gpl, int *r_initframe, int *r_endframe) { - *r_initframe = gpl->actframe->framenum; - *r_endframe = gpl->actframe->framenum; + *r_initframe = gpl->actframe->framenum; + *r_endframe = gpl->actframe->framenum; - for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { - if (gpf->flag & GP_FRAME_SELECT) { - if (gpf->framenum < *r_initframe) { - *r_initframe = gpf->framenum; - } - if (gpf->framenum > *r_endframe) { - *r_endframe = gpf->framenum; - } - } - } + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + if (gpf->flag & GP_FRAME_SELECT) { + if (gpf->framenum < *r_initframe) { + *r_initframe = gpf->framenum; + } + if (gpf->framenum > *r_endframe) { + *r_endframe = gpf->framenum; + } + } + } } /** @@ -1561,261 +1563,270 @@ void BKE_gpencil_get_range_selected(bGPDlayer *gpl, int *r_initframe, int *r_end * \param f_end: Number of last selected frame * \param cur_falloff: Curve with falloff factors */ -float BKE_gpencil_multiframe_falloff_calc(bGPDframe *gpf, int actnum, int f_init, int f_end, CurveMapping *cur_falloff) -{ - float fnum = 0.5f; /* default mid curve */ - float value; - - /* check curve is available */ - if (cur_falloff == NULL) { - return 1.0f; - } - - /* frames to the right of the active frame */ - if (gpf->framenum < actnum) { - fnum = (float)(gpf->framenum - f_init) / (actnum - f_init); - fnum *= 0.5f; - value = curvemapping_evaluateF(cur_falloff, 0, fnum); - } - /* frames to the left of the active frame */ - else if (gpf->framenum > actnum) { - fnum = (float)(gpf->framenum - actnum) / (f_end - actnum); - fnum *= 0.5f; - value = curvemapping_evaluateF(cur_falloff, 0, fnum + 0.5f); - } - else { - value = 1.0f; - } - - return value; +float BKE_gpencil_multiframe_falloff_calc( + bGPDframe *gpf, int actnum, int f_init, int f_end, CurveMapping *cur_falloff) +{ + float fnum = 0.5f; /* default mid curve */ + float value; + + /* check curve is available */ + if (cur_falloff == NULL) { + return 1.0f; + } + + /* frames to the right of the active frame */ + if (gpf->framenum < actnum) { + fnum = (float)(gpf->framenum - f_init) / (actnum - f_init); + fnum *= 0.5f; + value = curvemapping_evaluateF(cur_falloff, 0, fnum); + } + /* frames to the left of the active frame */ + else if (gpf->framenum > actnum) { + fnum = (float)(gpf->framenum - actnum) / (f_end - actnum); + fnum *= 0.5f; + value = curvemapping_evaluateF(cur_falloff, 0, fnum + 0.5f); + } + else { + value = 1.0f; + } + + return value; } /* remove strokes using a material */ void BKE_gpencil_material_index_remove(bGPdata *gpd, int index) { - bGPDstroke *gps, *gpsn; - - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { - for (gps = gpf->strokes.first; gps; gps = gpsn) { - gpsn = gps->next; - if (gps->mat_nr == index) { - if (gps->points) { - MEM_freeN(gps->points); - } - if (gps->dvert) { - BKE_gpencil_free_stroke_weights(gps); - MEM_freeN(gps->dvert); - } - if (gps->triangles) MEM_freeN(gps->triangles); - BLI_freelinkN(&gpf->strokes, gps); - } - else { - /* reassign strokes */ - if (gps->mat_nr > index) { - gps->mat_nr--; - } - } - } - } - } -} - -void BKE_gpencil_material_remap(struct bGPdata *gpd, const unsigned int *remap, unsigned int remap_len) -{ - const short remap_len_short = (short)remap_len; + bGPDstroke *gps, *gpsn; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + if (gps->mat_nr == index) { + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } + if (gps->triangles) + MEM_freeN(gps->triangles); + BLI_freelinkN(&gpf->strokes, gps); + } + else { + /* reassign strokes */ + if (gps->mat_nr > index) { + gps->mat_nr--; + } + } + } + } + } +} + +void BKE_gpencil_material_remap(struct bGPdata *gpd, + const unsigned int *remap, + unsigned int remap_len) +{ + const short remap_len_short = (short)remap_len; #define MAT_NR_REMAP(n) \ - if (n < remap_len_short) { \ - BLI_assert(n >= 0 && remap[n] < remap_len_short); \ - n = remap[n]; \ - } ((void)0) - - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { - for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { - /* reassign strokes */ - MAT_NR_REMAP(gps->mat_nr); - } - } - } + if (n < remap_len_short) { \ + BLI_assert(n >= 0 && remap[n] < remap_len_short); \ + n = remap[n]; \ + } \ + ((void)0) + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + /* reassign strokes */ + MAT_NR_REMAP(gps->mat_nr); + } + } + } #undef MAT_NR_REMAP - } /* statistics functions */ void BKE_gpencil_stats_update(bGPdata *gpd) { - gpd->totlayer = 0; - gpd->totframe = 0; - gpd->totstroke = 0; - gpd->totpoint = 0; - - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - gpd->totlayer++; - for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { - gpd->totframe++; - for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { - gpd->totstroke++; - gpd->totpoint += gps->totpoints; - } - } - } + gpd->totlayer = 0; + gpd->totframe = 0; + gpd->totstroke = 0; + gpd->totpoint = 0; + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + gpd->totlayer++; + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + gpd->totframe++; + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + gpd->totstroke++; + gpd->totpoint += gps->totpoints; + } + } + } } /* get material index (0-based like mat_nr not actcol) */ int BKE_gpencil_object_material_get_index(Object *ob, Material *ma) { - short *totcol = give_totcolp(ob); - Material *read_ma = NULL; - for (short i = 0; i < *totcol; i++) { - read_ma = give_current_material(ob, i + 1); - if (ma == read_ma) { - return i; - } - } + short *totcol = give_totcolp(ob); + Material *read_ma = NULL; + for (short i = 0; i < *totcol; i++) { + read_ma = give_current_material(ob, i + 1); + if (ma == read_ma) { + return i; + } + } - return -1; + return -1; } /* Get points of stroke always flat to view not affected by camera view or view position */ -void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction) +void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points, + int totpoints, + float (*points2d)[2], + int *r_direction) { - BLI_assert(totpoints >= 2); + BLI_assert(totpoints >= 2); - const bGPDspoint *pt0 = &points[0]; - const bGPDspoint *pt1 = &points[1]; - const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)]; + const bGPDspoint *pt0 = &points[0]; + const bGPDspoint *pt1 = &points[1]; + const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)]; - float locx[3]; - float locy[3]; - float loc3[3]; - float normal[3]; + float locx[3]; + float locy[3]; + float loc3[3]; + float normal[3]; - /* local X axis (p0 -> p1) */ - sub_v3_v3v3(locx, &pt1->x, &pt0->x); + /* local X axis (p0 -> p1) */ + sub_v3_v3v3(locx, &pt1->x, &pt0->x); - /* point vector at 3/4 */ - float v3[3]; - if (totpoints == 2) { - mul_v3_v3fl(v3, &pt3->x, 0.001f); - } - else { - copy_v3_v3(v3, &pt3->x); - } + /* point vector at 3/4 */ + float v3[3]; + if (totpoints == 2) { + mul_v3_v3fl(v3, &pt3->x, 0.001f); + } + else { + copy_v3_v3(v3, &pt3->x); + } - sub_v3_v3v3(loc3, v3, &pt0->x); + sub_v3_v3v3(loc3, v3, &pt0->x); - /* vector orthogonal to polygon plane */ - cross_v3_v3v3(normal, locx, loc3); + /* vector orthogonal to polygon plane */ + cross_v3_v3v3(normal, locx, loc3); - /* local Y axis (cross to normal/x axis) */ - cross_v3_v3v3(locy, normal, locx); + /* local Y axis (cross to normal/x axis) */ + cross_v3_v3v3(locy, normal, locx); - /* Normalize vectors */ - normalize_v3(locx); - normalize_v3(locy); + /* Normalize vectors */ + normalize_v3(locx); + normalize_v3(locy); - /* Get all points in local space */ - for (int i = 0; i < totpoints; i++) { - const bGPDspoint *pt = &points[i]; - float loc[3]; + /* Get all points in local space */ + for (int i = 0; i < totpoints; i++) { + const bGPDspoint *pt = &points[i]; + float loc[3]; - /* Get local space using first point as origin */ - sub_v3_v3v3(loc, &pt->x, &pt0->x); + /* Get local space using first point as origin */ + sub_v3_v3v3(loc, &pt->x, &pt0->x); - points2d[i][0] = dot_v3v3(loc, locx); - points2d[i][1] = dot_v3v3(loc, locy); - } + points2d[i][0] = dot_v3v3(loc, locx); + points2d[i][1] = dot_v3v3(loc, locy); + } - /* Concave (-1), Convex (1), or Autodetect (0)? */ - *r_direction = (int)locy[2]; + /* Concave (-1), Convex (1), or Autodetect (0)? */ + *r_direction = (int)locy[2]; } /* Get points of stroke always flat to view not affected by camera view or view position * using another stroke as reference */ -void BKE_gpencil_stroke_2d_flat_ref( - const bGPDspoint *ref_points, int ref_totpoints, - const bGPDspoint *points, int totpoints, - float(*points2d)[2], const float scale, int *r_direction) -{ - BLI_assert(totpoints >= 2); - - const bGPDspoint *pt0 = &ref_points[0]; - const bGPDspoint *pt1 = &ref_points[1]; - const bGPDspoint *pt3 = &ref_points[(int)(ref_totpoints * 0.75)]; - - float locx[3]; - float locy[3]; - float loc3[3]; - float normal[3]; - - /* local X axis (p0 -> p1) */ - sub_v3_v3v3(locx, &pt1->x, &pt0->x); - - /* point vector at 3/4 */ - float v3[3]; - if (totpoints == 2) { - mul_v3_v3fl(v3, &pt3->x, 0.001f); - } - else { - copy_v3_v3(v3, &pt3->x); - } - - sub_v3_v3v3(loc3, v3, &pt0->x); - - /* vector orthogonal to polygon plane */ - cross_v3_v3v3(normal, locx, loc3); - - /* local Y axis (cross to normal/x axis) */ - cross_v3_v3v3(locy, normal, locx); - - /* Normalize vectors */ - normalize_v3(locx); - normalize_v3(locy); - - /* Get all points in local space */ - for (int i = 0; i < totpoints; i++) { - const bGPDspoint *pt = &points[i]; - float loc[3]; - float v1[3]; - float vn[3] = { 0.0f, 0.0f, 0.0f }; - - /* apply scale to extremes of the stroke to get better collision detection - * the scale is divided to get more control in the UI parameter - */ - /* first point */ - if (i == 0) { - const bGPDspoint *pt_next = &points[i + 1]; - sub_v3_v3v3(vn, &pt->x, &pt_next->x); - normalize_v3(vn); - mul_v3_fl(vn, scale / 10.0f); - add_v3_v3v3(v1, &pt->x, vn); - } - /* last point */ - else if (i == totpoints - 1) { - const bGPDspoint *pt_prev = &points[i - 1]; - sub_v3_v3v3(vn, &pt->x, &pt_prev->x); - normalize_v3(vn); - mul_v3_fl(vn, scale / 10.0f); - add_v3_v3v3(v1, &pt->x, vn); - } - else { - copy_v3_v3(v1, &pt->x); - } - - /* Get local space using first point as origin (ref stroke) */ - sub_v3_v3v3(loc, v1, &pt0->x); - - points2d[i][0] = dot_v3v3(loc, locx); - points2d[i][1] = dot_v3v3(loc, locy); - } - - /* Concave (-1), Convex (1), or Autodetect (0)? */ - *r_direction = (int)locy[2]; +void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points, + int ref_totpoints, + const bGPDspoint *points, + int totpoints, + float (*points2d)[2], + const float scale, + int *r_direction) +{ + BLI_assert(totpoints >= 2); + + const bGPDspoint *pt0 = &ref_points[0]; + const bGPDspoint *pt1 = &ref_points[1]; + const bGPDspoint *pt3 = &ref_points[(int)(ref_totpoints * 0.75)]; + + float locx[3]; + float locy[3]; + float loc3[3]; + float normal[3]; + + /* local X axis (p0 -> p1) */ + sub_v3_v3v3(locx, &pt1->x, &pt0->x); + + /* point vector at 3/4 */ + float v3[3]; + if (totpoints == 2) { + mul_v3_v3fl(v3, &pt3->x, 0.001f); + } + else { + copy_v3_v3(v3, &pt3->x); + } + + sub_v3_v3v3(loc3, v3, &pt0->x); + + /* vector orthogonal to polygon plane */ + cross_v3_v3v3(normal, locx, loc3); + + /* local Y axis (cross to normal/x axis) */ + cross_v3_v3v3(locy, normal, locx); + + /* Normalize vectors */ + normalize_v3(locx); + normalize_v3(locy); + + /* Get all points in local space */ + for (int i = 0; i < totpoints; i++) { + const bGPDspoint *pt = &points[i]; + float loc[3]; + float v1[3]; + float vn[3] = {0.0f, 0.0f, 0.0f}; + + /* apply scale to extremes of the stroke to get better collision detection + * the scale is divided to get more control in the UI parameter + */ + /* first point */ + if (i == 0) { + const bGPDspoint *pt_next = &points[i + 1]; + sub_v3_v3v3(vn, &pt->x, &pt_next->x); + normalize_v3(vn); + mul_v3_fl(vn, scale / 10.0f); + add_v3_v3v3(v1, &pt->x, vn); + } + /* last point */ + else if (i == totpoints - 1) { + const bGPDspoint *pt_prev = &points[i - 1]; + sub_v3_v3v3(vn, &pt->x, &pt_prev->x); + normalize_v3(vn); + mul_v3_fl(vn, scale / 10.0f); + add_v3_v3v3(v1, &pt->x, vn); + } + else { + copy_v3_v3(v1, &pt->x); + } + + /* Get local space using first point as origin (ref stroke) */ + sub_v3_v3v3(loc, v1, &pt0->x); + + points2d[i][0] = dot_v3v3(loc, locx); + points2d[i][1] = dot_v3v3(loc, locy); + } + + /* Concave (-1), Convex (1), or Autodetect (0)? */ + *r_direction = (int)locy[2]; } /** @@ -1824,91 +1835,91 @@ void BKE_gpencil_stroke_2d_flat_ref( */ bool BKE_gpencil_trim_stroke(bGPDstroke *gps) { - if (gps->totpoints < 4) { - return false; - } - bool intersect = false; - int start, end; - float point[3]; - /* loop segments from start until we have an intersection */ - for (int i = 0; i < gps->totpoints - 2; i++) { - start = i; - bGPDspoint *a = &gps->points[start]; - bGPDspoint *b = &gps->points[start + 1]; - for (int j = start + 2; j < gps->totpoints - 1; j++) { - end = j + 1; - bGPDspoint *c = &gps->points[j]; - bGPDspoint *d = &gps->points[end]; - float pointb[3]; - /* get intersection */ - if (isect_line_line_v3(&a->x, &b->x, &c->x, &d->x, point, pointb)) { - if (len_v3(point) > 0.0f) { - float closest[3]; - /* check intersection is on both lines */ - float lambda = closest_to_line_v3(closest, point, &a->x, &b->x); - if ((lambda <= 0.0f) || (lambda >= 1.0f)) { - continue; - } - lambda = closest_to_line_v3(closest, point, &c->x, &d->x); - if ((lambda <= 0.0f) || (lambda >= 1.0f)) { - continue; - } - else { - intersect = true; - break; - } - } - } - } - if (intersect) { - break; - } - } - - /* trim unwanted points */ - if (intersect) { - - /* save points */ - bGPDspoint *old_points = MEM_dupallocN(gps->points); - MDeformVert *old_dvert = NULL; - MDeformVert *dvert_src = NULL; - - if (gps->dvert != NULL) { - old_dvert = MEM_dupallocN(gps->dvert); - } - - /* resize gps */ - int newtot = end - start + 1; - - gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * newtot); - if (gps->dvert != NULL) { - gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot); - } - - for (int i = 0; i < newtot; i++) { - int idx = start + i; - bGPDspoint *pt_src = &old_points[idx]; - bGPDspoint *pt_new = &gps->points[i]; - memcpy(pt_new, pt_src, sizeof(bGPDspoint)); - if (gps->dvert != NULL) { - dvert_src = &old_dvert[idx]; - MDeformVert *dvert = &gps->dvert[i]; - memcpy(dvert, dvert_src, sizeof(MDeformVert)); - if (dvert_src->dw) { - memcpy(dvert->dw, dvert_src->dw, sizeof(MDeformWeight)); - } - } - if (idx == start || idx == end) { - copy_v3_v3(&pt_new->x, point); - } - } - - gps->flag |= GP_STROKE_RECALC_GEOMETRY; - gps->tot_triangles = 0; - gps->totpoints = newtot; - - MEM_SAFE_FREE(old_points); - MEM_SAFE_FREE(old_dvert); - } - return intersect; + if (gps->totpoints < 4) { + return false; + } + bool intersect = false; + int start, end; + float point[3]; + /* loop segments from start until we have an intersection */ + for (int i = 0; i < gps->totpoints - 2; i++) { + start = i; + bGPDspoint *a = &gps->points[start]; + bGPDspoint *b = &gps->points[start + 1]; + for (int j = start + 2; j < gps->totpoints - 1; j++) { + end = j + 1; + bGPDspoint *c = &gps->points[j]; + bGPDspoint *d = &gps->points[end]; + float pointb[3]; + /* get intersection */ + if (isect_line_line_v3(&a->x, &b->x, &c->x, &d->x, point, pointb)) { + if (len_v3(point) > 0.0f) { + float closest[3]; + /* check intersection is on both lines */ + float lambda = closest_to_line_v3(closest, point, &a->x, &b->x); + if ((lambda <= 0.0f) || (lambda >= 1.0f)) { + continue; + } + lambda = closest_to_line_v3(closest, point, &c->x, &d->x); + if ((lambda <= 0.0f) || (lambda >= 1.0f)) { + continue; + } + else { + intersect = true; + break; + } + } + } + } + if (intersect) { + break; + } + } + + /* trim unwanted points */ + if (intersect) { + + /* save points */ + bGPDspoint *old_points = MEM_dupallocN(gps->points); + MDeformVert *old_dvert = NULL; + MDeformVert *dvert_src = NULL; + + if (gps->dvert != NULL) { + old_dvert = MEM_dupallocN(gps->dvert); + } + + /* resize gps */ + int newtot = end - start + 1; + + gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * newtot); + if (gps->dvert != NULL) { + gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot); + } + + for (int i = 0; i < newtot; i++) { + int idx = start + i; + bGPDspoint *pt_src = &old_points[idx]; + bGPDspoint *pt_new = &gps->points[i]; + memcpy(pt_new, pt_src, sizeof(bGPDspoint)); + if (gps->dvert != NULL) { + dvert_src = &old_dvert[idx]; + MDeformVert *dvert = &gps->dvert[i]; + memcpy(dvert, dvert_src, sizeof(MDeformVert)); + if (dvert_src->dw) { + memcpy(dvert->dw, dvert_src->dw, sizeof(MDeformWeight)); + } + } + if (idx == start || idx == end) { + copy_v3_v3(&pt_new->x, point); + } + } + + gps->flag |= GP_STROKE_RECALC_GEOMETRY; + gps->tot_triangles = 0; + gps->totpoints = newtot; + + MEM_SAFE_FREE(old_points); + MEM_SAFE_FREE(old_dvert); + } + return intersect; } |