Blender  V3.3
MOD_cloth.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
8 #include <string.h>
9 
10 #include "BLI_utildefines.h"
11 
12 #include "BLI_listbase.h"
13 
14 #include "BLT_translation.h"
15 
16 #include "DNA_cloth_types.h"
17 #include "DNA_defaults.h"
18 #include "DNA_key_types.h"
19 #include "DNA_mesh_types.h"
20 #include "DNA_object_force_types.h"
21 #include "DNA_object_types.h"
22 #include "DNA_scene_types.h"
23 #include "DNA_screen_types.h"
24 
25 #include "MEM_guardedalloc.h"
26 
27 #include "BKE_cloth.h"
28 #include "BKE_context.h"
29 #include "BKE_effect.h"
30 #include "BKE_global.h"
31 #include "BKE_key.h"
32 #include "BKE_lib_id.h"
33 #include "BKE_lib_query.h"
34 #include "BKE_mesh.h"
35 #include "BKE_modifier.h"
36 #include "BKE_pointcache.h"
37 #include "BKE_screen.h"
38 
39 #include "UI_interface.h"
40 #include "UI_resources.h"
41 
42 #include "RNA_access.h"
43 #include "RNA_prototypes.h"
44 
45 #include "DEG_depsgraph_physics.h"
46 #include "DEG_depsgraph_query.h"
47 
48 #include "MOD_ui_common.h"
49 #include "MOD_util.h"
50 
51 static void initData(ModifierData *md)
52 {
54 
55  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(clmd, modifier));
56 
60 
61  clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
62 
63  /* check for alloc failing */
64  if (!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache) {
65  return;
66  }
67 
68  if (!clmd->sim_parms->effector_weights) {
70  }
71 
72  if (clmd->point_cache) {
73  clmd->point_cache->step = 1;
74  }
75 }
76 
77 static void deformVerts(ModifierData *md,
78  const ModifierEvalContext *ctx,
79  Mesh *mesh,
80  float (*vertexCos)[3],
81  int verts_num)
82 {
83  Mesh *mesh_src;
86 
87  /* check for alloc failing */
88  if (!clmd->sim_parms || !clmd->coll_parms) {
89  initData(md);
90 
91  if (!clmd->sim_parms || !clmd->coll_parms) {
92  return;
93  }
94  }
95 
96  if (mesh == NULL) {
97  mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, verts_num, false, false);
98  }
99  else {
100  /* Not possible to use get_mesh() in this case as we'll modify its vertices
101  * and get_mesh() would return 'mesh' directly. */
102  mesh_src = (Mesh *)BKE_id_copy_ex(NULL, (ID *)mesh, NULL, LIB_ID_COPY_LOCALIZE);
103  }
104 
105  /* TODO(sergey): For now it actually duplicates logic from DerivedMesh.cc
106  * and needs some more generic solution. But starting experimenting with
107  * this so close to the release is not that nice..
108  *
109  * Also hopefully new cloth system will arrive soon..
110  */
111  if (mesh == NULL && clmd->sim_parms->shapekey_rest) {
113  clmd->sim_parms->shapekey_rest);
114  if (kb && kb->data != NULL) {
115  float(*layerorco)[3];
116  if (!(layerorco = CustomData_get_layer(&mesh_src->vdata, CD_CLOTH_ORCO))) {
117  layerorco = CustomData_add_layer(
118  &mesh_src->vdata, CD_CLOTH_ORCO, CD_CALLOC, NULL, mesh_src->totvert);
119  }
120 
121  memcpy(layerorco, kb->data, sizeof(float[3]) * verts_num);
122  }
123  }
124 
125  BKE_mesh_vert_coords_apply(mesh_src, vertexCos);
126 
127  clothModifier_do(clmd, ctx->depsgraph, scene, ctx->object, mesh_src, vertexCos);
128 
129  BKE_id_free(NULL, mesh_src);
130 }
131 
133 {
134  ClothModifierData *clmd = (ClothModifierData *)md;
135  if (clmd != NULL) {
138  ctx->object,
139  clmd->coll_parms->group,
141  NULL,
142  "Cloth Collision");
143  }
145  ctx->node, ctx->object, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
146  }
147  DEG_add_modifier_to_transform_relation(ctx->node, "Cloth Modifier");
148 }
149 
150 static void requiredDataMask(Object *UNUSED(ob),
151  ModifierData *md,
152  CustomData_MeshMasks *r_cddata_masks)
153 {
154  ClothModifierData *clmd = (ClothModifierData *)md;
155 
156  if (cloth_uses_vgroup(clmd)) {
157  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
158  }
159 
160  if (clmd->sim_parms->shapekey_rest != 0) {
161  r_cddata_masks->vmask |= CD_MASK_CLOTH_ORCO;
162  }
163 }
164 
165 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
166 {
167  const ClothModifierData *clmd = (const ClothModifierData *)md;
168  ClothModifierData *tclmd = (ClothModifierData *)target;
169 
170  if (tclmd->sim_parms) {
171  if (tclmd->sim_parms->effector_weights) {
173  }
174  MEM_freeN(tclmd->sim_parms);
175  }
176 
177  if (tclmd->coll_parms) {
178  MEM_freeN(tclmd->coll_parms);
179  }
180 
182  if (flag & LIB_ID_COPY_SET_COPIED_ON_WRITE) {
183  /* Share the cache with the original object's modifier. */
185  tclmd->ptcaches = clmd->ptcaches;
186  tclmd->point_cache = clmd->point_cache;
187  }
188  else {
189  const int clmd_point_cache_index = BLI_findindex(&clmd->ptcaches, clmd->point_cache);
190  BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches, flag);
191  tclmd->point_cache = BLI_findlink(&tclmd->ptcaches, clmd_point_cache_index);
192  }
193 
194  tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
195  if (clmd->sim_parms->effector_weights) {
197  }
198  tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
199  tclmd->clothObject = NULL;
200  tclmd->hairdata = NULL;
201  tclmd->solver_result = NULL;
202 }
203 
204 static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *UNUSED(md))
205 {
206  return true;
207 }
208 
209 static void freeData(ModifierData *md)
210 {
211  ClothModifierData *clmd = (ClothModifierData *)md;
212 
213  if (clmd) {
214  if (G.debug & G_DEBUG_SIMDATA) {
215  printf("clothModifier_freeData\n");
216  }
217 
219 
220  if (clmd->sim_parms) {
221  if (clmd->sim_parms->effector_weights) {
223  }
224  MEM_freeN(clmd->sim_parms);
225  }
226  if (clmd->coll_parms) {
227  MEM_freeN(clmd->coll_parms);
228  }
229 
230  if (md->flag & eModifierFlag_SharedCaches) {
232  }
233  else {
235  }
236  clmd->point_cache = NULL;
237 
238  if (clmd->hairdata) {
239  MEM_freeN(clmd->hairdata);
240  }
241 
242  if (clmd->solver_result) {
243  MEM_freeN(clmd->solver_result);
244  }
245  }
246 }
247 
248 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
249 {
250  ClothModifierData *clmd = (ClothModifierData *)md;
251 
252  if (clmd->coll_parms) {
253  walk(userData, ob, (ID **)&clmd->coll_parms->group, IDWALK_CB_NOP);
254  }
255 
256  if (clmd->sim_parms && clmd->sim_parms->effector_weights) {
257  walk(userData, ob, (ID **)&clmd->sim_parms->effector_weights->group, IDWALK_CB_USER);
258  }
259 }
260 
261 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
262 {
263  uiLayout *layout = panel->layout;
264 
266 
267  uiItemL(layout, TIP_("Settings are inside the Physics tab"), ICON_NONE);
268 
269  modifier_panel_end(layout, ptr);
270 }
271 
272 static void panelRegister(ARegionType *region_type)
273 {
275 }
276 
278  /* name */ N_("Cloth"),
279  /* structName */ "ClothModifierData",
280  /* structSize */ sizeof(ClothModifierData),
281  /* srna */ &RNA_ClothModifier,
282  /* type */ eModifierTypeType_OnlyDeform,
285  /* icon */ ICON_MOD_CLOTH,
286 
287  /* copyData */ copyData,
288 
289  /* deformVerts */ deformVerts,
290  /* deformMatrices */ NULL,
291  /* deformVertsEM */ NULL,
292  /* deformMatricesEM */ NULL,
293  /* modifyMesh */ NULL,
294  /* modifyGeometrySet */ NULL,
295 
296  /* initData */ initData,
297  /* requiredDataMask */ requiredDataMask,
298  /* freeData */ freeData,
299  /* isDisabled */ NULL,
300  /* updateDepsgraph */ updateDepsgraph,
301  /* dependsOnTime */ dependsOnTime,
302  /* dependsOnNormals */ NULL,
303  /* foreachIDLink */ foreachIDLink,
304  /* foreachTexLink */ NULL,
305  /* freeRuntimeData */ NULL,
306  /* panelRegister */ panelRegister,
307  /* blendWrite */ NULL,
308  /* blendRead */ NULL,
309 };
typedef float(TangentPoint)[2]
int cloth_uses_vgroup(struct ClothModifierData *clmd)
Definition: cloth.c:593
void clothModifier_do(struct ClothModifierData *clmd, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct Mesh *me, float(*vertexCos)[3])
Definition: cloth.c:314
void cloth_free_modifier_extern(struct ClothModifierData *clmd)
Definition: cloth.c:491
@ CD_CALLOC
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.cc:2776
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
Definition: effect.c:58
@ G_DEBUG_SIMDATA
Definition: BKE_global.h:192
struct KeyBlock * BKE_keyblock_from_key(struct Key *key, int index)
Definition: key.c:1913
struct Key * BKE_key_from_object(struct Object *ob)
Definition: key.c:1803
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
Definition: BKE_lib_id.h:143
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:187
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, int flag)
void BKE_id_free(struct Main *bmain, void *idv)
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
void BKE_mesh_vert_coords_apply(struct Mesh *mesh, const float(*vert_coords)[3])
Definition: mesh.cc:1834
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:107
@ eModifierTypeFlag_Single
Definition: BKE_modifier.h:93
@ eModifierTypeFlag_UsesPointCache
Definition: BKE_modifier.h:90
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:66
@ eModifierTypeType_OnlyDeform
Definition: BKE_modifier.h:44
struct PointCache * BKE_ptcache_copy_list(struct ListBase *ptcaches_new, const struct ListBase *ptcaches_old, int flag)
struct PointCache * BKE_ptcache_add(struct ListBase *ptcaches)
Definition: pointcache.c:3014
void BKE_ptcache_free_list(struct ListBase *ptcaches)
Definition: pointcache.c:3052
#define BLI_assert(a)
Definition: BLI_assert.h:46
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define UNUSED(x)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define TIP_(msgid)
void DEG_add_modifier_to_transform_relation(struct DepsNodeHandle *node_handle, const char *description)
void DEG_add_collision_relations(struct DepsNodeHandle *handle, struct Object *object, struct Collection *collection, unsigned int modifier_type, DEG_CollobjFilterFunction filter_function, const char *name)
void DEG_add_forcefield_relations(struct DepsNodeHandle *handle, struct Object *object, struct EffectorWeights *eff, bool add_absorption, int skip_forcefield, const char *name)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ CLOTH_COLLSETTINGS_FLAG_ENABLED
#define CD_MASK_MDEFORMVERT
@ CD_CLOTH_ORCO
#define CD_MASK_CLOTH_ORCO
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
#define DNA_struct_default_alloc(struct_name)
Definition: DNA_defaults.h:32
@ eModifierFlag_SharedCaches
struct ClothModifierData ClothModifierData
@ eModifierType_Cloth
@ eModifierType_Collision
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *UNUSED(md))
Definition: MOD_cloth.c:204
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
Definition: MOD_cloth.c:165
static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float(*vertexCos)[3], int verts_num)
Definition: MOD_cloth.c:77
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
Definition: MOD_cloth.c:132
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
Definition: MOD_cloth.c:248
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
Definition: MOD_cloth.c:261
static void initData(ModifierData *md)
Definition: MOD_cloth.c:51
static void panelRegister(ARegionType *region_type)
Definition: MOD_cloth.c:272
ModifierTypeInfo modifierType_Cloth
Definition: MOD_cloth.c:277
static void freeData(ModifierData *md)
Definition: MOD_cloth.c:209
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition: MOD_cloth.c:150
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
Definition: MOD_ui_common.c:91
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
Mesh * MOD_deform_mesh_eval_get(Object *ob, struct BMEditMesh *em, Mesh *mesh, const float(*vertexCos)[3], const int verts_num, const bool use_normals, const bool use_orco)
Definition: MOD_util.c:167
#define C
Definition: RandGen.cpp:25
void uiItemL(uiLayout *layout, const char *name, int icon)
Scene scene
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
#define G(x, y, z)
struct Collection * group
struct ListBase ptcaches
struct ClothSolverResult * solver_result
struct ClothHairData * hairdata
struct Cloth * clothObject
struct PointCache * point_cache
struct ClothSimSettings * sim_parms
struct ClothCollSettings * coll_parms
struct EffectorWeights * effector_weights
struct Collection * group
Definition: DNA_ID.h:368
void * data
Definition: DNA_key_types.h:50
CustomData vdata
int totvert
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:140
struct Object * object
Definition: BKE_modifier.h:141
struct DepsNodeHandle * node
Definition: BKE_modifier.h:134
struct uiLayout * layout
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480