Cleanup: BKE_library: remove 'test' param of id_copy.
[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 blender/modifiers/intern/MOD_cloth.c
21  *  \ingroup modifiers
22  */
23
24 #include <string.h>
25
26 #include "DNA_cloth_types.h"
27 #include "DNA_key_types.h"
28 #include "DNA_mesh_types.h"
29 #include "DNA_scene_types.h"
30 #include "DNA_object_types.h"
31
32 #include "MEM_guardedalloc.h"
33
34 #include "BLI_listbase.h"
35 #include "BLI_utildefines.h"
36
37 #include "BKE_cloth.h"
38 #include "BKE_effect.h"
39 #include "BKE_global.h"
40 #include "BKE_key.h"
41 #include "BKE_library.h"
42 #include "BKE_library_query.h"
43 #include "BKE_mesh.h"
44 #include "BKE_modifier.h"
45 #include "BKE_pointcache.h"
46
47 #include "DEG_depsgraph_physics.h"
48 #include "DEG_depsgraph_query.h"
49
50 #include "MOD_util.h"
51
52 static void initData(ModifierData *md)
53 {
54         ClothModifierData *clmd = (ClothModifierData *) md;
55
56         clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
57         clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
58         clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
59
60         /* check for alloc failing */
61         if (!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache)
62                 return;
63
64         cloth_init(clmd);
65 }
66
67 static void deformVerts(
68         ModifierData *md, const ModifierEvalContext *ctx,
69         Mesh *mesh, float (*vertexCos)[3],
70         int numVerts)
71 {
72         Mesh *mesh_src;
73         ClothModifierData *clmd = (ClothModifierData *) md;
74         Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
75
76         /* check for alloc failing */
77         if (!clmd->sim_parms || !clmd->coll_parms) {
78                 initData(md);
79
80                 if (!clmd->sim_parms || !clmd->coll_parms)
81                         return;
82         }
83
84         if (mesh == NULL) {
85                 mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false);
86         }
87         else {
88                 /* Not possible to use get_mesh() in this case as we'll modify its vertices
89                  * and get_mesh() would return 'mesh' directly. */
90                 BKE_id_copy_ex(
91                         NULL, (ID *)mesh, (ID **)&mesh_src,
92                         LIB_ID_CREATE_NO_MAIN |
93                         LIB_ID_CREATE_NO_USER_REFCOUNT |
94                         LIB_ID_CREATE_NO_DEG_TAG |
95                         LIB_ID_COPY_NO_PREVIEW);
96         }
97
98         /* TODO(sergey): For now it actually duplicates logic from DerivedMesh.c
99          * and needs some more generic solution. But starting experimenting with
100          * this so close to the release is not that nice..
101          *
102          * Also hopefully new cloth system will arrive soon..
103          */
104         if (mesh == NULL && clmd->sim_parms->shapekey_rest) {
105                 KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ctx->object),
106                                                      clmd->sim_parms->shapekey_rest);
107                 if (kb && kb->data != NULL) {
108                         float (*layerorco)[3];
109                         if (!(layerorco = CustomData_get_layer(&mesh_src->vdata, CD_CLOTH_ORCO))) {
110                                 layerorco = CustomData_add_layer(&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                 DEG_add_collision_relations(ctx->node, ctx->object, clmd->coll_parms->group, eModifierType_Collision, NULL, "Cloth Collision");
129                 DEG_add_forcefield_relations(ctx->node, ctx->object, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
130         }
131         DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Cloth Modifier");
132 }
133
134 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
135 {
136         CustomDataMask dataMask = 0;
137         ClothModifierData *clmd = (ClothModifierData *)md;
138
139         if (cloth_uses_vgroup(clmd))
140                 dataMask |= CD_MASK_MDEFORMVERT;
141
142         if (clmd->sim_parms->shapekey_rest != 0)
143                 dataMask |= CD_MASK_CLOTH_ORCO;
144
145         return dataMask;
146 }
147
148 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
149 {
150         const ClothModifierData *clmd = (const ClothModifierData *) md;
151         ClothModifierData *tclmd = (ClothModifierData *) target;
152
153         if (tclmd->sim_parms) {
154                 if (tclmd->sim_parms->effector_weights)
155                         MEM_freeN(tclmd->sim_parms->effector_weights);
156                 MEM_freeN(tclmd->sim_parms);
157         }
158
159         if (tclmd->coll_parms)
160                 MEM_freeN(tclmd->coll_parms);
161
162         BKE_ptcache_free_list(&tclmd->ptcaches);
163         if (flag & LIB_ID_CREATE_NO_MAIN) {
164                 /* Share the cache with the original object's modifier. */
165                 tclmd->modifier.flag |= eModifierFlag_SharedCaches;
166                 tclmd->ptcaches = clmd->ptcaches;
167                 tclmd->point_cache = clmd->point_cache;
168         }
169         else {
170                 tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches);
171                 tclmd->point_cache->step = 1;
172         }
173
174         tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
175         if (clmd->sim_parms->effector_weights)
176                 tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
177         tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
178         tclmd->clothObject = NULL;
179         tclmd->hairdata = NULL;
180         tclmd->solver_result = NULL;
181 }
182
183 static bool dependsOnTime(ModifierData *UNUSED(md))
184 {
185         return true;
186 }
187
188 static void freeData(ModifierData *md)
189 {
190         ClothModifierData *clmd = (ClothModifierData *) md;
191
192         if (clmd) {
193                 if (G.debug & G_DEBUG_SIMDATA) {
194                         printf("clothModifier_freeData\n");
195                 }
196
197                 cloth_free_modifier_extern(clmd);
198
199                 if (clmd->sim_parms) {
200                         if (clmd->sim_parms->effector_weights)
201                                 MEM_freeN(clmd->sim_parms->effector_weights);
202                         MEM_freeN(clmd->sim_parms);
203                 }
204                 if (clmd->coll_parms)
205                         MEM_freeN(clmd->coll_parms);
206
207                 if (md->flag & eModifierFlag_SharedCaches) {
208                         BLI_listbase_clear(&clmd->ptcaches);
209                 }
210                 else {
211                         BKE_ptcache_free_list(&clmd->ptcaches);
212                 }
213                 clmd->point_cache = NULL;
214
215                 if (clmd->hairdata)
216                         MEM_freeN(clmd->hairdata);
217
218                 if (clmd->solver_result)
219                         MEM_freeN(clmd->solver_result);
220         }
221 }
222
223 static void foreachIDLink(
224         ModifierData *md, Object *ob,
225         IDWalkFunc walk, void *userData)
226 {
227         ClothModifierData *clmd = (ClothModifierData *) md;
228
229         if (clmd->coll_parms) {
230                 walk(userData, ob, (ID **)&clmd->coll_parms->group, IDWALK_CB_NOP);
231         }
232
233         if (clmd->sim_parms && clmd->sim_parms->effector_weights) {
234                 walk(userData, ob, (ID **)&clmd->sim_parms->effector_weights->group, IDWALK_CB_NOP);
235         }
236 }
237
238 ModifierTypeInfo modifierType_Cloth = {
239         /* name */              "Cloth",
240         /* structName */        "ClothModifierData",
241         /* structSize */        sizeof(ClothModifierData),
242         /* type */              eModifierTypeType_OnlyDeform,
243         /* flags */             eModifierTypeFlag_AcceptsMesh |
244                                 eModifierTypeFlag_UsesPointCache |
245                                 eModifierTypeFlag_Single,
246
247         /* copyData */          copyData,
248
249         /* deformVerts_DM */    NULL,
250         /* deformMatrices_DM */ NULL,
251         /* deformVertsEM_DM */  NULL,
252         /* deformMatricesEM_DM*/NULL,
253         /* applyModifier_DM */  NULL,
254
255         /* deformVerts */       deformVerts,
256         /* deformMatrices */    NULL,
257         /* deformVertsEM */     NULL,
258         /* deformMatricesEM */  NULL,
259         /* applyModifier */     NULL,
260
261         /* initData */          initData,
262         /* requiredDataMask */  requiredDataMask,
263         /* freeData */          freeData,
264         /* isDisabled */        NULL,
265         /* updateDepsgraph */   updateDepsgraph,
266         /* dependsOnTime */     dependsOnTime,
267         /* dependsOnNormals */  NULL,
268         /* foreachObjectLink */ NULL,
269         /* foreachIDLink */     foreachIDLink,
270         /* foreachTexLink */    NULL,
271 };