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/gpencil_modifiers/intern/MOD_gpencilbuild.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/gpencil_modifiers/intern/MOD_gpencilbuild.c')
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c847
1 files changed, 423 insertions, 424 deletions
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
index d057c7083bd..5f7f8165ed2 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
@@ -47,27 +47,27 @@
static void initData(GpencilModifierData *md)
{
- BuildGpencilModifierData *gpmd = (BuildGpencilModifierData *)md;
+ BuildGpencilModifierData *gpmd = (BuildGpencilModifierData *)md;
- /* We deliberately set this range to the half the default
- * frame-range to have an immediate effect to suggest use-cases
- */
- gpmd->start_frame = 1;
- gpmd->end_frame = 125;
+ /* We deliberately set this range to the half the default
+ * frame-range to have an immediate effect to suggest use-cases
+ */
+ gpmd->start_frame = 1;
+ gpmd->end_frame = 125;
- /* Init default length of each build effect - Nothing special */
- gpmd->start_delay = 0.0f;
- gpmd->length = 100.0f;
+ /* Init default length of each build effect - Nothing special */
+ gpmd->start_delay = 0.0f;
+ gpmd->length = 100.0f;
}
static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
{
- BKE_gpencil_modifier_copyData_generic(md, target);
+ BKE_gpencil_modifier_copyData_generic(md, target);
}
static bool dependsOnTime(GpencilModifierData *UNUSED(md))
{
- return true;
+ return true;
}
/* ******************************************** */
@@ -88,19 +88,19 @@ static bool dependsOnTime(GpencilModifierData *UNUSED(md))
/* Remove a particular stroke */
static void clear_stroke(bGPDframe *gpf, bGPDstroke *gps)
{
- BLI_remlink(&gpf->strokes, gps);
- BKE_gpencil_free_stroke(gps);
+ BLI_remlink(&gpf->strokes, gps);
+ BKE_gpencil_free_stroke(gps);
}
/* Clear all strokes in frame */
static void gpf_clear_all_strokes(bGPDframe *gpf)
{
- bGPDstroke *gps, *gps_next;
- for (gps = gpf->strokes.first; gps; gps = gps_next) {
- gps_next = gps->next;
- clear_stroke(gpf, gps);
- }
- BLI_listbase_clear(&gpf->strokes);
+ bGPDstroke *gps, *gps_next;
+ for (gps = gpf->strokes.first; gps; gps = gps_next) {
+ gps_next = gps->next;
+ clear_stroke(gpf, gps);
+ }
+ BLI_listbase_clear(&gpf->strokes);
}
/* Reduce the number of points in the stroke
@@ -108,185 +108,183 @@ static void gpf_clear_all_strokes(bGPDframe *gpf)
* Note: This won't be called if all points are present/removed
* TODO: Allow blending of growing/shrinking tip (e.g. for more gradual transitions)
*/
-static void reduce_stroke_points(bGPDstroke *gps, const int num_points, const eBuildGpencil_Transition transition)
+static void reduce_stroke_points(bGPDstroke *gps,
+ const int num_points,
+ const eBuildGpencil_Transition transition)
{
- bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * num_points, __func__);
- MDeformVert *new_dvert = NULL;
- if (gps->dvert != NULL) {
- new_dvert = MEM_callocN(sizeof(MDeformVert) * num_points, __func__);
- }
-
- /* Which end should points be removed from */
- // TODO: free stroke weights
- switch (transition) {
- case GP_BUILD_TRANSITION_GROW: /* Show in forward order = Remove ungrown-points from end of stroke */
- case GP_BUILD_TRANSITION_SHRINK: /* Hide in reverse order = Remove dead-points from end of stroke */
- {
- /* copy over point data */
- memcpy(new_points, gps->points, sizeof(bGPDspoint) * num_points);
- if (gps->dvert != NULL) {
- memcpy(new_dvert, gps->dvert, sizeof(MDeformVert) * num_points);
-
- /* free unused point weights */
- for (int i = num_points; i < gps->totpoints; i++) {
- MDeformVert *dvert = &gps->dvert[i];
- BKE_gpencil_free_point_weights(dvert);
- }
- }
- break;
- }
-
- /* Hide in forward order = Remove points from start of stroke */
- case GP_BUILD_TRANSITION_FADE:
- {
- /* num_points is the number of points left after reducing.
- * We need to know how many to remove
- */
- const int offset = gps->totpoints - num_points;
-
- /* copy over point data */
- memcpy(new_points, gps->points + offset, sizeof(bGPDspoint) * num_points);
- if (gps->dvert != NULL) {
- memcpy(new_dvert, gps->dvert + offset, sizeof(MDeformVert) * num_points);
-
- /* free unused weights */
- for (int i = 0; i < offset; i++) {
- MDeformVert *dvert = &gps->dvert[i];
- BKE_gpencil_free_point_weights(dvert);
- }
- }
- break;
- }
-
- default:
- printf("ERROR: Unknown transition %d in %s()\n", (int)transition, __func__);
- break;
- }
-
- /* replace stroke geometry */
- MEM_SAFE_FREE(gps->points);
- MEM_SAFE_FREE(gps->dvert);
- gps->points = new_points;
- gps->dvert = new_dvert;
- gps->totpoints = num_points;
-
- /* mark stroke as needing to have its geometry caches rebuilt */
- gps->flag |= GP_STROKE_RECALC_GEOMETRY;
- gps->tot_triangles = 0;
- MEM_SAFE_FREE(gps->triangles);
+ bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * num_points, __func__);
+ MDeformVert *new_dvert = NULL;
+ if (gps->dvert != NULL) {
+ new_dvert = MEM_callocN(sizeof(MDeformVert) * num_points, __func__);
+ }
+
+ /* Which end should points be removed from */
+ // TODO: free stroke weights
+ switch (transition) {
+ case GP_BUILD_TRANSITION_GROW: /* Show in forward order = Remove ungrown-points from end of stroke */
+ case GP_BUILD_TRANSITION_SHRINK: /* Hide in reverse order = Remove dead-points from end of stroke */
+ {
+ /* copy over point data */
+ memcpy(new_points, gps->points, sizeof(bGPDspoint) * num_points);
+ if (gps->dvert != NULL) {
+ memcpy(new_dvert, gps->dvert, sizeof(MDeformVert) * num_points);
+
+ /* free unused point weights */
+ for (int i = num_points; i < gps->totpoints; i++) {
+ MDeformVert *dvert = &gps->dvert[i];
+ BKE_gpencil_free_point_weights(dvert);
+ }
+ }
+ break;
+ }
+
+ /* Hide in forward order = Remove points from start of stroke */
+ case GP_BUILD_TRANSITION_FADE: {
+ /* num_points is the number of points left after reducing.
+ * We need to know how many to remove
+ */
+ const int offset = gps->totpoints - num_points;
+
+ /* copy over point data */
+ memcpy(new_points, gps->points + offset, sizeof(bGPDspoint) * num_points);
+ if (gps->dvert != NULL) {
+ memcpy(new_dvert, gps->dvert + offset, sizeof(MDeformVert) * num_points);
+
+ /* free unused weights */
+ for (int i = 0; i < offset; i++) {
+ MDeformVert *dvert = &gps->dvert[i];
+ BKE_gpencil_free_point_weights(dvert);
+ }
+ }
+ break;
+ }
+
+ default:
+ printf("ERROR: Unknown transition %d in %s()\n", (int)transition, __func__);
+ break;
+ }
+
+ /* replace stroke geometry */
+ MEM_SAFE_FREE(gps->points);
+ MEM_SAFE_FREE(gps->dvert);
+ gps->points = new_points;
+ gps->dvert = new_dvert;
+ gps->totpoints = num_points;
+
+ /* mark stroke as needing to have its geometry caches rebuilt */
+ gps->flag |= GP_STROKE_RECALC_GEOMETRY;
+ gps->tot_triangles = 0;
+ MEM_SAFE_FREE(gps->triangles);
}
/* --------------------------------------------- */
/* Stroke Data Table Entry - This represents one stroke being generated */
typedef struct tStrokeBuildDetails {
- bGPDstroke *gps;
+ bGPDstroke *gps;
- /* Indices - first/last indices for the stroke's points (overall) */
- size_t start_idx, end_idx;
+ /* Indices - first/last indices for the stroke's points (overall) */
+ size_t start_idx, end_idx;
- /* Number of points - Cache for more convenient access */
- int totpoints;
+ /* Number of points - Cache for more convenient access */
+ int totpoints;
} tStrokeBuildDetails;
-
/* Sequential - Show strokes one after the other */
static void build_sequential(BuildGpencilModifierData *mmd, bGPDframe *gpf, float fac)
{
- const size_t tot_strokes = BLI_listbase_count(&gpf->strokes);
- bGPDstroke *gps;
- size_t i;
-
- /* 1) Compute proportion of time each stroke should occupy */
- /* NOTE: This assumes that the total number of points won't overflow! */
- tStrokeBuildDetails *table = MEM_callocN(sizeof(tStrokeBuildDetails) * tot_strokes, __func__);
- size_t totpoints = 0;
-
- /* 1.1) First pass - Tally up points */
- for (gps = gpf->strokes.first, i = 0; gps; gps = gps->next, i++) {
- tStrokeBuildDetails *cell = &table[i];
-
- cell->gps = gps;
- cell->totpoints = gps->totpoints;
-
- totpoints += cell->totpoints;
- }
-
- /* 1.2) Second pass - Compute the overall indices for points */
- for (i = 0; i < tot_strokes; i++) {
- tStrokeBuildDetails *cell = &table[i];
-
- if (i == 0) {
- cell->start_idx = 0;
- }
- else {
- cell->start_idx = (cell - 1)->end_idx;
- }
- cell->end_idx = cell->start_idx + cell->totpoints - 1;
- }
-
-
- /* 2) Determine the global indices for points that should be visible */
- size_t first_visible = 0;
- size_t last_visible = 0;
-
- switch (mmd->transition) {
- /* Show in forward order
- * - As fac increases, the number of visible points increases
- */
- case GP_BUILD_TRANSITION_GROW:
- first_visible = 0; /* always visible */
- last_visible = (size_t)roundf(totpoints * fac);
- break;
-
- /* Hide in reverse order
- * - As fac increases, the number of points visible at the end decreases
- */
- case GP_BUILD_TRANSITION_SHRINK:
- first_visible = 0; /* always visible (until last point removed) */
- last_visible = (size_t)(totpoints * (1.0f - fac));
- break;
-
- /* Hide in forward order
- * - As fac increases, the early points start getting hidden
- */
- case GP_BUILD_TRANSITION_FADE:
- first_visible = (size_t)(totpoints * fac);
- last_visible = totpoints; /* i.e. visible until the end, unless first overlaps this */
- break;
- }
-
-
- /* 3) Go through all strokes, deciding which to keep, and/or how much of each to keep */
- for (i = 0; i < tot_strokes; i++) {
- tStrokeBuildDetails *cell = &table[i];
-
- /* Determine what portion of the stroke is visible */
- if ((cell->end_idx < first_visible) || (cell->start_idx > last_visible)) {
- /* Not visible at all - Either ended before */
- clear_stroke(gpf, cell->gps);
- }
- else {
- /* Some proportion of stroke is visible */
- /* XXX: Will the transition settings still be valid now? */
- if ((first_visible <= cell->start_idx) && (last_visible >= cell->end_idx)) {
- /* Do nothing - whole stroke is visible */
- }
- else if (first_visible > cell->start_idx) {
- /* Starts partway through this stroke */
- int num_points = cell->end_idx - first_visible;
- reduce_stroke_points(cell->gps, num_points, mmd->transition);
- }
- else {
- /* Ends partway through this stroke */
- int num_points = last_visible - cell->start_idx;
- reduce_stroke_points(cell->gps, num_points, mmd->transition);
- }
- }
- }
-
- /* Free table */
- MEM_freeN(table);
+ const size_t tot_strokes = BLI_listbase_count(&gpf->strokes);
+ bGPDstroke *gps;
+ size_t i;
+
+ /* 1) Compute proportion of time each stroke should occupy */
+ /* NOTE: This assumes that the total number of points won't overflow! */
+ tStrokeBuildDetails *table = MEM_callocN(sizeof(tStrokeBuildDetails) * tot_strokes, __func__);
+ size_t totpoints = 0;
+
+ /* 1.1) First pass - Tally up points */
+ for (gps = gpf->strokes.first, i = 0; gps; gps = gps->next, i++) {
+ tStrokeBuildDetails *cell = &table[i];
+
+ cell->gps = gps;
+ cell->totpoints = gps->totpoints;
+
+ totpoints += cell->totpoints;
+ }
+
+ /* 1.2) Second pass - Compute the overall indices for points */
+ for (i = 0; i < tot_strokes; i++) {
+ tStrokeBuildDetails *cell = &table[i];
+
+ if (i == 0) {
+ cell->start_idx = 0;
+ }
+ else {
+ cell->start_idx = (cell - 1)->end_idx;
+ }
+ cell->end_idx = cell->start_idx + cell->totpoints - 1;
+ }
+
+ /* 2) Determine the global indices for points that should be visible */
+ size_t first_visible = 0;
+ size_t last_visible = 0;
+
+ switch (mmd->transition) {
+ /* Show in forward order
+ * - As fac increases, the number of visible points increases
+ */
+ case GP_BUILD_TRANSITION_GROW:
+ first_visible = 0; /* always visible */
+ last_visible = (size_t)roundf(totpoints * fac);
+ break;
+
+ /* Hide in reverse order
+ * - As fac increases, the number of points visible at the end decreases
+ */
+ case GP_BUILD_TRANSITION_SHRINK:
+ first_visible = 0; /* always visible (until last point removed) */
+ last_visible = (size_t)(totpoints * (1.0f - fac));
+ break;
+
+ /* Hide in forward order
+ * - As fac increases, the early points start getting hidden
+ */
+ case GP_BUILD_TRANSITION_FADE:
+ first_visible = (size_t)(totpoints * fac);
+ last_visible = totpoints; /* i.e. visible until the end, unless first overlaps this */
+ break;
+ }
+
+ /* 3) Go through all strokes, deciding which to keep, and/or how much of each to keep */
+ for (i = 0; i < tot_strokes; i++) {
+ tStrokeBuildDetails *cell = &table[i];
+
+ /* Determine what portion of the stroke is visible */
+ if ((cell->end_idx < first_visible) || (cell->start_idx > last_visible)) {
+ /* Not visible at all - Either ended before */
+ clear_stroke(gpf, cell->gps);
+ }
+ else {
+ /* Some proportion of stroke is visible */
+ /* XXX: Will the transition settings still be valid now? */
+ if ((first_visible <= cell->start_idx) && (last_visible >= cell->end_idx)) {
+ /* Do nothing - whole stroke is visible */
+ }
+ else if (first_visible > cell->start_idx) {
+ /* Starts partway through this stroke */
+ int num_points = cell->end_idx - first_visible;
+ reduce_stroke_points(cell->gps, num_points, mmd->transition);
+ }
+ else {
+ /* Ends partway through this stroke */
+ int num_points = last_visible - cell->start_idx;
+ reduce_stroke_points(cell->gps, num_points, mmd->transition);
+ }
+ }
+ }
+
+ /* Free table */
+ MEM_freeN(table);
}
/* --------------------------------------------- */
@@ -296,255 +294,256 @@ static void build_sequential(BuildGpencilModifierData *mmd, bGPDframe *gpf, floa
// TODO: Allow varying speeds? Scaling of progress?
static void build_concurrent(BuildGpencilModifierData *mmd, bGPDframe *gpf, float fac)
{
- bGPDstroke *gps, *gps_next;
- int max_points = 0;
-
- const bool reverse = (mmd->transition != GP_BUILD_TRANSITION_GROW);
-
- /* 1) Determine the longest stroke, to figure out when short strokes should start */
- /* FIXME: A *really* long stroke here could dwarf everything else, causing bad timings */
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
- if (gps->totpoints > max_points) {
- max_points = gps->totpoints;
- }
- }
- if (max_points == 0) {
- printf("ERROR: Strokes are all empty (GP Build Modifier: %s)\n", __func__);
- return;
- }
-
- /* 2) For each stroke, determine how it should be handled */
- for (gps = gpf->strokes.first; gps; gps = gps_next) {
- gps_next = gps->next;
-
- /* Relative Length of Stroke - Relative to the longest stroke,
- * what proportion of the available time should this stroke use
- */
- const float relative_len = (float)gps->totpoints / (float)max_points;
-
- /* Determine how many points should be left in the stroke */
- int num_points = 0;
-
- switch (mmd->time_alignment) {
- case GP_BUILD_TIMEALIGN_START: /* all start on frame 1 */
- {
- /* Build effect occurs over when fac = 0, to fac = relative_len */
- if (fac <= relative_len) {
- /* Scale fac to fit relative_len */
- /* FIXME: prevent potential div by zero (e.g. very short stroke vs one very long one) */
- const float scaled_fac = fac / relative_len;
-
- if (reverse) {
- num_points = (int)roundf((1.0f - scaled_fac) * gps->totpoints);
- }
- else {
- num_points = (int)roundf(scaled_fac * gps->totpoints);
- }
- }
- else {
- /* Build effect has ended */
- if (reverse) {
- num_points = 0;
- }
- else {
- num_points = gps->totpoints;
- }
- }
-
- break;
- }
- case GP_BUILD_TIMEALIGN_END: /* all end on same frame */
- {
- /* Build effect occurs over 1.0 - relative_len, to 1.0 (i.e. over the end of the range) */
- const float start_fac = 1.0f - relative_len;
-
- if (fac >= start_fac) {
- /* FIXME: prevent potential div by zero (e.g. very short stroke vs one very long one) */
- const float scaled_fac = (fac - start_fac) / relative_len;
-
- if (reverse) {
- num_points = (int)roundf((1.0f - scaled_fac) * gps->totpoints);
- }
- else {
- num_points = (int)roundf(scaled_fac * gps->totpoints);
- }
- }
- else {
- /* Build effect hasn't started */
- if (reverse) {
- num_points = gps->totpoints;
- }
- else {
- num_points = 0;
- }
- }
-
- break;
- }
-
- /* TODO... */
- }
-
- /* Modify the stroke geometry */
- if (num_points <= 0) {
- /* Nothing Left - Delete the stroke */
- clear_stroke(gpf, gps);
- }
- else if (num_points < gps->totpoints) {
- /* Remove some points */
- reduce_stroke_points(gps, num_points, mmd->transition);
- }
- }
+ bGPDstroke *gps, *gps_next;
+ int max_points = 0;
+
+ const bool reverse = (mmd->transition != GP_BUILD_TRANSITION_GROW);
+
+ /* 1) Determine the longest stroke, to figure out when short strokes should start */
+ /* FIXME: A *really* long stroke here could dwarf everything else, causing bad timings */
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ if (gps->totpoints > max_points) {
+ max_points = gps->totpoints;
+ }
+ }
+ if (max_points == 0) {
+ printf("ERROR: Strokes are all empty (GP Build Modifier: %s)\n", __func__);
+ return;
+ }
+
+ /* 2) For each stroke, determine how it should be handled */
+ for (gps = gpf->strokes.first; gps; gps = gps_next) {
+ gps_next = gps->next;
+
+ /* Relative Length of Stroke - Relative to the longest stroke,
+ * what proportion of the available time should this stroke use
+ */
+ const float relative_len = (float)gps->totpoints / (float)max_points;
+
+ /* Determine how many points should be left in the stroke */
+ int num_points = 0;
+
+ switch (mmd->time_alignment) {
+ case GP_BUILD_TIMEALIGN_START: /* all start on frame 1 */
+ {
+ /* Build effect occurs over when fac = 0, to fac = relative_len */
+ if (fac <= relative_len) {
+ /* Scale fac to fit relative_len */
+ /* FIXME: prevent potential div by zero (e.g. very short stroke vs one very long one) */
+ const float scaled_fac = fac / relative_len;
+
+ if (reverse) {
+ num_points = (int)roundf((1.0f - scaled_fac) * gps->totpoints);
+ }
+ else {
+ num_points = (int)roundf(scaled_fac * gps->totpoints);
+ }
+ }
+ else {
+ /* Build effect has ended */
+ if (reverse) {
+ num_points = 0;
+ }
+ else {
+ num_points = gps->totpoints;
+ }
+ }
+
+ break;
+ }
+ case GP_BUILD_TIMEALIGN_END: /* all end on same frame */
+ {
+ /* Build effect occurs over 1.0 - relative_len, to 1.0 (i.e. over the end of the range) */
+ const float start_fac = 1.0f - relative_len;
+
+ if (fac >= start_fac) {
+ /* FIXME: prevent potential div by zero (e.g. very short stroke vs one very long one) */
+ const float scaled_fac = (fac - start_fac) / relative_len;
+
+ if (reverse) {
+ num_points = (int)roundf((1.0f - scaled_fac) * gps->totpoints);
+ }
+ else {
+ num_points = (int)roundf(scaled_fac * gps->totpoints);
+ }
+ }
+ else {
+ /* Build effect hasn't started */
+ if (reverse) {
+ num_points = gps->totpoints;
+ }
+ else {
+ num_points = 0;
+ }
+ }
+
+ break;
+ }
+
+ /* TODO... */
+ }
+
+ /* Modify the stroke geometry */
+ if (num_points <= 0) {
+ /* Nothing Left - Delete the stroke */
+ clear_stroke(gpf, gps);
+ }
+ else if (num_points < gps->totpoints) {
+ /* Remove some points */
+ reduce_stroke_points(gps, num_points, mmd->transition);
+ }
+ }
}
/* --------------------------------------------- */
/* Entry-point for Build Modifier */
-static void generateStrokes(
- GpencilModifierData *md, Depsgraph *depsgraph,
- Object *UNUSED(ob), bGPDlayer *gpl, bGPDframe *gpf)
+static void generateStrokes(GpencilModifierData *md,
+ Depsgraph *depsgraph,
+ Object *UNUSED(ob),
+ bGPDlayer *gpl,
+ bGPDframe *gpf)
{
- BuildGpencilModifierData *mmd = (BuildGpencilModifierData *)md;
- const bool reverse = (mmd->transition != GP_BUILD_TRANSITION_GROW);
-
- const float ctime = DEG_get_ctime(depsgraph);
- //printf("GP Build Modifier - %f\n", ctime);
-
- /* Early exit if it's an empty frame */
- if (gpf->strokes.first == NULL) {
- return;
- }
-
- /* Omit layer if filter by layer */
- if (mmd->layername[0] != '\0') {
- if ((mmd->flag & GP_BUILD_INVERT_LAYER) == 0) {
- if (!STREQ(mmd->layername, gpl->info)) {
- return;
- }
- }
- else {
- if (STREQ(mmd->layername, gpl->info)) {
- return;
- }
- }
- }
- /* verify layer pass */
- if (mmd->layer_pass > 0) {
- if ((mmd->flag & GP_BUILD_INVERT_LAYERPASS) == 0) {
- if (gpl->pass_index != mmd->layer_pass) {
- return;
- }
- }
- else {
- if (gpl->pass_index == mmd->layer_pass) {
- return;
- }
- }
- }
-
- /* Early exit if outside of the frame range for this modifier
- * (e.g. to have one forward, and one backwards modifier)
- */
- if (mmd->flag & GP_BUILD_RESTRICT_TIME) {
- if ((ctime < mmd->start_frame) || (ctime > mmd->end_frame)) {
- return;
- }
- }
-
- /* Compute start and end frames for the animation effect
- * By default, the upper bound is given by the "maximum length" setting
- */
- float start_frame = gpf->framenum + mmd->start_delay;
- float end_frame = gpf->framenum + mmd->length;
-
- if (gpf->next) {
- /* Use the next frame or upper bound as end frame, whichever is lower/closer */
- end_frame = MIN2(end_frame, gpf->next->framenum);
- }
-
-
- /* Early exit if current frame is outside start/end bounds */
- /* NOTE: If we're beyond the next/prev frames (if existent), then we wouldn't have this problem anyway... */
- if (ctime < start_frame) {
- /* Before Start - Animation hasn't started. Display initial state. */
- if (reverse) {
- /* 1) Reverse = Start with all, end with nothing.
- * ==> Do nothing (everything already present)
- */
- }
- else {
- /* 2) Forward Order = Start with nothing, end with the full frame.
- * ==> Free all strokes, and return an empty frame
- */
- gpf_clear_all_strokes(gpf);
- }
-
- /* Early exit */
- return;
- }
- else if (ctime >= end_frame) {
- /* Past End - Animation finished. Display final result. */
- if (reverse) {
- /* 1) Reverse = Start with all, end with nothing.
- * ==> Free all strokes, and return an empty frame
- */
- gpf_clear_all_strokes(gpf);
- }
- else {
- /* 2) Forward Order = Start with nothing, end with the full frame.
- * ==> Do Nothing (everything already present)
- */
- }
-
- /* Early exit */
- return;
- }
-
-
- /* Determine how far along we are between the keyframes */
- float fac = (ctime - start_frame) / (end_frame - start_frame);
- //printf(" Progress on %d = %f (%f - %f)\n", gpf->framenum, fac, start_frame, end_frame);
-
- /* Time management mode */
- switch (mmd->mode) {
- case GP_BUILD_MODE_SEQUENTIAL:
- build_sequential(mmd, gpf, fac);
- break;
-
- case GP_BUILD_MODE_CONCURRENT:
- build_concurrent(mmd, gpf, fac);
- break;
-
- default:
- printf("Unsupported build mode (%d) for GP Build Modifier: '%s'\n", mmd->mode, mmd->modifier.name);
- break;
- }
+ BuildGpencilModifierData *mmd = (BuildGpencilModifierData *)md;
+ const bool reverse = (mmd->transition != GP_BUILD_TRANSITION_GROW);
+
+ const float ctime = DEG_get_ctime(depsgraph);
+ //printf("GP Build Modifier - %f\n", ctime);
+
+ /* Early exit if it's an empty frame */
+ if (gpf->strokes.first == NULL) {
+ return;
+ }
+
+ /* Omit layer if filter by layer */
+ if (mmd->layername[0] != '\0') {
+ if ((mmd->flag & GP_BUILD_INVERT_LAYER) == 0) {
+ if (!STREQ(mmd->layername, gpl->info)) {
+ return;
+ }
+ }
+ else {
+ if (STREQ(mmd->layername, gpl->info)) {
+ return;
+ }
+ }
+ }
+ /* verify layer pass */
+ if (mmd->layer_pass > 0) {
+ if ((mmd->flag & GP_BUILD_INVERT_LAYERPASS) == 0) {
+ if (gpl->pass_index != mmd->layer_pass) {
+ return;
+ }
+ }
+ else {
+ if (gpl->pass_index == mmd->layer_pass) {
+ return;
+ }
+ }
+ }
+
+ /* Early exit if outside of the frame range for this modifier
+ * (e.g. to have one forward, and one backwards modifier)
+ */
+ if (mmd->flag & GP_BUILD_RESTRICT_TIME) {
+ if ((ctime < mmd->start_frame) || (ctime > mmd->end_frame)) {
+ return;
+ }
+ }
+
+ /* Compute start and end frames for the animation effect
+ * By default, the upper bound is given by the "maximum length" setting
+ */
+ float start_frame = gpf->framenum + mmd->start_delay;
+ float end_frame = gpf->framenum + mmd->length;
+
+ if (gpf->next) {
+ /* Use the next frame or upper bound as end frame, whichever is lower/closer */
+ end_frame = MIN2(end_frame, gpf->next->framenum);
+ }
+
+ /* Early exit if current frame is outside start/end bounds */
+ /* NOTE: If we're beyond the next/prev frames (if existent), then we wouldn't have this problem anyway... */
+ if (ctime < start_frame) {
+ /* Before Start - Animation hasn't started. Display initial state. */
+ if (reverse) {
+ /* 1) Reverse = Start with all, end with nothing.
+ * ==> Do nothing (everything already present)
+ */
+ }
+ else {
+ /* 2) Forward Order = Start with nothing, end with the full frame.
+ * ==> Free all strokes, and return an empty frame
+ */
+ gpf_clear_all_strokes(gpf);
+ }
+
+ /* Early exit */
+ return;
+ }
+ else if (ctime >= end_frame) {
+ /* Past End - Animation finished. Display final result. */
+ if (reverse) {
+ /* 1) Reverse = Start with all, end with nothing.
+ * ==> Free all strokes, and return an empty frame
+ */
+ gpf_clear_all_strokes(gpf);
+ }
+ else {
+ /* 2) Forward Order = Start with nothing, end with the full frame.
+ * ==> Do Nothing (everything already present)
+ */
+ }
+
+ /* Early exit */
+ return;
+ }
+
+ /* Determine how far along we are between the keyframes */
+ float fac = (ctime - start_frame) / (end_frame - start_frame);
+ //printf(" Progress on %d = %f (%f - %f)\n", gpf->framenum, fac, start_frame, end_frame);
+
+ /* Time management mode */
+ switch (mmd->mode) {
+ case GP_BUILD_MODE_SEQUENTIAL:
+ build_sequential(mmd, gpf, fac);
+ break;
+
+ case GP_BUILD_MODE_CONCURRENT:
+ build_concurrent(mmd, gpf, fac);
+ break;
+
+ default:
+ printf("Unsupported build mode (%d) for GP Build Modifier: '%s'\n",
+ mmd->mode,
+ mmd->modifier.name);
+ break;
+ }
}
-
/* ******************************************** */
GpencilModifierTypeInfo modifierType_Gpencil_Build = {
- /* name */ "Build",
- /* structName */ "BuildGpencilModifierData",
- /* structSize */ sizeof(BuildGpencilModifierData),
- /* type */ eGpencilModifierTypeType_Gpencil,
- /* flags */ eGpencilModifierTypeFlag_NoApply,
-
- /* copyData */ copyData,
-
- /* deformStroke */ NULL,
- /* generateStrokes */ generateStrokes,
- /* bakeModifier */ NULL,
- /* remapTime */ NULL,
-
- /* initData */ initData,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ dependsOnTime,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* getDuplicationFactor */ NULL,
+ /* name */ "Build",
+ /* structName */ "BuildGpencilModifierData",
+ /* structSize */ sizeof(BuildGpencilModifierData),
+ /* type */ eGpencilModifierTypeType_Gpencil,
+ /* flags */ eGpencilModifierTypeFlag_NoApply,
+
+ /* copyData */ copyData,
+
+ /* deformStroke */ NULL,
+ /* generateStrokes */ generateStrokes,
+ /* bakeModifier */ NULL,
+ /* remapTime */ NULL,
+
+ /* initData */ initData,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ dependsOnTime,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* getDuplicationFactor */ NULL,
};