e220d5a5e85158e9de1ed6ed87ede54debe42b84
[blender.git] / source / blender / gpencil_modifiers / intern / MOD_gpenciltime.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2018, Blender Foundation
19  * This is a new part of Blender
20  *
21  * Contributor(s): Antonio Vazquez
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  *
25  */
26
27 /** \file blender/gpencil_modifiers/intern/MOD_gpenciltime.c
28  *  \ingroup modifiers
29  */
30
31 #include <stdio.h>
32 #include <string.h>
33
34 #include "BLI_utildefines.h"
35
36 #include "DNA_meshdata_types.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_gpencil_types.h"
40 #include "DNA_gpencil_modifier_types.h"
41
42 #include "BKE_colortools.h"
43 #include "BKE_context.h"
44 #include "BKE_deform.h"
45 #include "BKE_gpencil.h"
46 #include "BKE_gpencil_modifier.h"
47
48 #include "DEG_depsgraph.h"
49
50 #include "MOD_gpencil_util.h"
51 #include "MOD_gpencil_modifiertypes.h"
52
53 static void initData(GpencilModifierData *md)
54 {
55         TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)md;
56         gpmd->layername[0] = '\0';
57         gpmd->offset = 1;
58         gpmd->frame_scale = 1.0f;
59         gpmd->flag |= GP_TIME_KEEP_LOOP;
60         gpmd->sfra = 1;
61         gpmd->efra = 250;
62 }
63
64 static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
65 {
66         BKE_gpencil_modifier_copyData_generic(md, target);
67 }
68
69 static int remapTime(
70         struct GpencilModifierData *md, struct Depsgraph *UNUSED(depsgraph),
71         struct Scene *scene, struct Object *UNUSED(ob), struct bGPDlayer *gpl, int cfra)
72 {
73         TimeGpencilModifierData *mmd = (TimeGpencilModifierData *)md;
74         const bool custom = mmd->flag & GP_TIME_CUSTOM_RANGE;
75         const bool invgpl = mmd->flag & GP_TIME_INVERT_LAYER;
76         const bool invpass = mmd->flag & GP_TIME_INVERT_LAYERPASS;
77         int sfra = custom ? mmd->sfra : scene->r.sfra;
78         int efra = custom ? mmd->efra : scene->r.efra;
79         CLAMP_MIN(sfra, 1);
80         CLAMP_MIN(efra, 1);
81         const int time_range = efra - sfra + 1;
82         int offset = mmd->offset;
83         int segments = 0;
84
85         /* omit if filter by layer */
86         if (mmd->layername[0] != '\0') {
87                 if (invgpl == false) {
88                         if (!STREQ(mmd->layername, gpl->info)) {
89                                 return cfra;
90                         }
91                 }
92                 else {
93                         if (STREQ(mmd->layername, gpl->info)) {
94                                 return cfra;
95                         }
96                 }
97         }
98         /* verify pass */
99         if (mmd->layer_pass > 0) {
100                 if (invpass == false) {
101                         if (gpl->pass_index != mmd->layer_pass) {
102                                 return cfra;
103                         }
104                 }
105                 else {
106                         if (gpl->pass_index == mmd->layer_pass) {
107                                 return cfra;
108                         }
109                 }
110         }
111
112         /* if fix mode, return predefined frame number */
113         if (mmd->mode == GP_TIME_MODE_FIX) {
114                 return offset;
115         }
116
117         /* invert current frame number */
118         if (mmd->mode == GP_TIME_MODE_REVERSE) {
119                 cfra = efra - cfra + sfra;
120         }
121
122         /* apply frame scale */
123         cfra *= mmd->frame_scale;
124
125         /* verify offset never is greater than frame range */
126         if (abs(offset) > time_range) {
127                 offset = offset - ((offset / time_range) * time_range);
128         }
129
130         /* verify not outside range if loop is disabled */
131         if ((mmd->flag & GP_TIME_KEEP_LOOP) == 0) {
132                 if (cfra + offset < sfra) {
133                         return sfra;
134                 }
135                 if (cfra + offset > efra) {
136                         return efra;
137                 }
138         }
139
140         /* check frames before start */
141         if (cfra < sfra) {
142                 segments = ((cfra + sfra) / time_range);
143                 cfra = cfra + (segments * time_range);
144         }
145
146         /* check frames after end */
147         if (cfra > efra) {
148                 segments = ((cfra - sfra) / time_range);
149                 cfra = cfra - (segments * time_range);
150         }
151
152         if (mmd->flag & GP_TIME_KEEP_LOOP) {
153                 const int nfra = cfra + offset;
154
155                 /* if the sum of the cfra is out scene frame range, recalc */
156                 if (cfra + offset < sfra) {
157                         const int delta = abs(sfra - nfra);
158                         return efra - delta + 1;
159                 }
160                 else if (cfra + offset > efra) {
161                         return nfra - efra + sfra - 1;
162                 }
163         }
164
165         return cfra + offset;
166 }
167
168 GpencilModifierTypeInfo modifierType_Gpencil_Time = {
169         /* name */              "Time Offset",
170         /* structName */        "TimeGpencilModifierData",
171         /* structSize */        sizeof(TimeGpencilModifierData),
172         /* type */              eGpencilModifierTypeType_Gpencil,
173         /* flags */             eGpencilModifierTypeFlag_NoApply,
174
175         /* copyData */          copyData,
176
177         /* deformStroke */      NULL,
178         /* generateStrokes */   NULL,
179         /* bakeModifier */      NULL,
180         /* remapTime */         remapTime,
181
182         /* initData */          initData,
183         /* freeData */          NULL,
184         /* isDisabled */        NULL,
185         /* updateDepsgraph */   NULL,
186         /* dependsOnTime */     NULL,
187         /* foreachObjectLink */ NULL,
188         /* foreachIDLink */     NULL,
189         /* foreachTexLink */    NULL,
190 };