Fix T68943: GPencil Time modifier gets strange value in offset parameter
[blender.git] / source / blender / modifiers / intern / MOD_cloth.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software  Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup modifiers
22  */
23
24 #include <string.h>
25
26 #include "BLI_utildefines.h"
27
28 #include "BLI_listbase.h"
29
30 #include "DNA_cloth_types.h"
31 #include "DNA_key_types.h"
32 #include "DNA_mesh_types.h"
33 #include "DNA_scene_types.h"
34 #include "DNA_object_types.h"
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BKE_cloth.h"
39 #include "BKE_effect.h"
40 #include "BKE_global.h"
41 #include "BKE_key.h"
42 #include "BKE_library.h"
43 #include "BKE_library_query.h"
44 #include "BKE_mesh.h"
45 #include "BKE_modifier.h"
46 #include "BKE_pointcache.h"
47
48 #include "DEG_depsgraph_physics.h"
49 #include "DEG_depsgraph_query.h"
50
51 #include "MOD_util.h"
52
53 static void initData(ModifierData *md)
54 {
55   ClothModifierData *clmd = (ClothModifierData *)md;
56
57   clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
58   clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
59   clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
60
61   /* check for alloc failing */
62   if (!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache) {
63     return;
64   }
65
66   cloth_init(clmd);
67 }
68
69 static void deformVerts(ModifierData *md,
70                         const ModifierEvalContext *ctx,
71                         Mesh *mesh,
72                         float (*vertexCos)[3],
73                         int numVerts)
74 {
75   Mesh *mesh_src;
76   ClothModifierData *clmd = (ClothModifierData *)md;
77   Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
78
79   /* check for alloc failing */
80   if (!clmd->sim_parms || !clmd->coll_parms) {
81     initData(md);
82
83     if (!clmd->sim_parms || !clmd->coll_parms) {
84       return;
85     }
86   }
87
88   if (mesh == NULL) {
89     mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false);
90   }
91   else {
92     /* Not possible to use get_mesh() in this case as we'll modify its vertices
93      * and get_mesh() would return 'mesh' directly. */
94     BKE_id_copy_ex(NULL, (ID *)mesh, (ID **)&mesh_src, LIB_ID_COPY_LOCALIZE);
95   }
96
97   /* TODO(sergey): For now it actually duplicates logic from DerivedMesh.c
98    * and needs some more generic solution. But starting experimenting with
99    * this so close to the release is not that nice..
100    *
101    * Also hopefully new cloth system will arrive soon..
102    */
103   if (mesh == NULL && clmd->sim_parms->shapekey_rest) {
104     KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ctx->object),
105                                          clmd->sim_parms->shapekey_rest);
106     if (kb && kb->data != NULL) {
107       float(*layerorco)[3];
108       if (!(layerorco = CustomData_get_layer(&mesh_src->vdata, CD_CLOTH_ORCO))) {
109         layerorco = CustomData_add_layer(
110             &mesh_src->vdata, CD_CLOTH_ORCO, CD_CALLOC, NULL, mesh_src->totvert);
111       }
112
113       memcpy(layerorco, kb->data, sizeof(float) * 3 * numVerts);
114     }
115   }
116
117   BKE_mesh_apply_vert_coords(mesh_src, vertexCos);
118
119   clothModifier_do(clmd, ctx->depsgraph, scene, ctx->object, mesh_src, vertexCos);
120
121   BKE_id_free(NULL, mesh_src);
122 }
123
124 static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
125 {
126   ClothModifierData *clmd = (ClothModifierData *)md;
127   if (clmd != NULL) {
128     if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) {
129       DEG_add_collision_relations(ctx->node,
130                                   ctx->object,
131                                   clmd->coll_parms->group,
132                                   eModifierType_Collision,
133                                   NULL,
134                                   "Cloth Collision");
135     }
136     DEG_add_forcefield_relations(
137         ctx->node, ctx->object, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
138   }
139   DEG_add_modifier_to_transform_relation(ctx->node, "Cloth Modifier");
140 }
141
142 static void requiredDataMask(Object *UNUSED(ob),
143                              ModifierData *md,
144                              CustomData_MeshMasks *r_cddata_masks)
145 {
146   ClothModifierData *clmd = (ClothModifierData *)md;
147
148   if (cloth_uses_vgroup(clmd)) {
149     r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
150   }
151
152   if (clmd->sim_parms->shapekey_rest != 0) {
153     r_cddata_masks->vmask |= CD_MASK_CLOTH_ORCO;
154   }
155 }
156
157 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
158 {
159   const ClothModifierData *clmd = (const ClothModifierData *)md;
160   ClothModifierData *tclmd = (ClothModifierData *)target;
161
162   if (tclmd->sim_parms) {
163     if (tclmd->sim_parms->effector_weights) {
164       MEM_freeN(tclmd->sim_parms->effector_weights);
165     }
166     MEM_freeN(tclmd->sim_parms);
167   }
168
169   if (tclmd->coll_parms) {
170     MEM_freeN(tclmd->coll_parms);
171   }
172
173   BKE_ptcache_free_list(&tclmd->ptcaches);
174   if (flag & LIB_ID_CREATE_NO_MAIN) {
175     /* Share the cache with the original object's modifier. */
176     tclmd->modifier.flag |= eModifierFlag_SharedCaches;
177     tclmd->ptcaches = clmd->ptcaches;
178     tclmd->point_cache = clmd->point_cache;
179   }
180   else {
181     tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches);
182     tclmd->point_cache->step = 1;
183   }
184
185   tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
186   if (clmd->sim_parms->effector_weights) {
187     tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
188   }
189   tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
190   tclmd->clothObject = NULL;
191   tclmd->hairdata = NULL;
192   tclmd->solver_result = NULL;
193 }
194
195 static bool dependsOnTime(ModifierData *UNUSED(md))
196 {
197   return true;
198 }
199
200 static void freeData(ModifierData *md)
201 {
202   ClothModifierData *clmd = (ClothModifierData *)md;
203
204   if (clmd) {
205     if (G.debug & G_DEBUG_SIMDATA) {
206       printf("clothModifier_freeData\n");
207     }
208
209     cloth_free_modifier_extern(clmd);
210
211     if (clmd->sim_parms) {
212       if (clmd->sim_parms->effector_weights) {
213         MEM_freeN(clmd->sim_parms->effector_weights);
214       }
215       MEM_freeN(clmd->sim_parms);
216     }
217     if (clmd->coll_parms) {
218       MEM_freeN(clmd->coll_parms);
219     }
220
221     if (md->flag & eModifierFlag_SharedCaches) {
222       BLI_listbase_clear(&clmd->ptcaches);
223     }
224     else {
225       BKE_ptcache_free_list(&clmd->ptcaches);
226     }
227     clmd->point_cache = NULL;
228
229     if (clmd->hairdata) {
230       MEM_freeN(clmd->hairdata);
231     }
232
233     if (clmd->solver_result) {
234       MEM_freeN(clmd->solver_result);
235     }
236   }
237 }
238
239 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
240 {
241   ClothModifierData *clmd = (ClothModifierData *)md;
242
243   if (clmd->coll_parms) {
244     walk(userData, ob, (ID **)&clmd->coll_parms->group, IDWALK_CB_NOP);
245   }
246
247   if (clmd->sim_parms && clmd->sim_parms->effector_weights) {
248     walk(userData, ob, (ID **)&clmd->sim_parms->effector_weights->group, IDWALK_CB_NOP);
249   }
250 }
251
252 ModifierTypeInfo modifierType_Cloth = {
253     /* name */ "Cloth",
254     /* structName */ "ClothModifierData",
255     /* structSize */ sizeof(ClothModifierData),
256     /* type */ eModifierTypeType_OnlyDeform,
257     /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache |
258         eModifierTypeFlag_Single,
259
260     /* copyData */ copyData,
261
262     /* deformVerts */ deformVerts,
263     /* deformMatrices */ NULL,
264     /* deformVertsEM */ NULL,
265     /* deformMatricesEM */ NULL,
266     /* applyModifier */ NULL,
267
268     /* initData */ initData,
269     /* requiredDataMask */ requiredDataMask,
270     /* freeData */ freeData,
271     /* isDisabled */ NULL,
272     /* updateDepsgraph */ updateDepsgraph,
273     /* dependsOnTime */ dependsOnTime,
274     /* dependsOnNormals */ NULL,
275     /* foreachObjectLink */ NULL,
276     /* foreachIDLink */ foreachIDLink,
277     /* foreachTexLink */ NULL,
278     /* freeRuntimeData */ NULL,
279 };