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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/blenkernel/intern/gpencil.c
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (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.c2605
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;
}