Blender  V2.93
MOD_cloth.c
Go to the documentation of this file.
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 
24 #include <string.h>
25 
26 #include "BLI_utildefines.h"
27 
28 #include "BLI_listbase.h"
29 
30 #include "BLT_translation.h"
31 
32 #include "DNA_cloth_types.h"
33 #include "DNA_defaults.h"
34 #include "DNA_key_types.h"
35 #include "DNA_mesh_types.h"
36 #include "DNA_object_force_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_screen_types.h"
40 
41 #include "MEM_guardedalloc.h"
42 
43 #include "BKE_cloth.h"
44 #include "BKE_context.h"
45 #include "BKE_effect.h"
46 #include "BKE_global.h"
47 #include "BKE_key.h"
48 #include "BKE_lib_id.h"
49 #include "BKE_lib_query.h"
50 #include "BKE_mesh.h"
51 #include "BKE_modifier.h"
52 #include "BKE_pointcache.h"
53 #include "BKE_screen.h"
54 
55 #include "UI_interface.h"
56 #include "UI_resources.h"
57 
58 #include "RNA_access.h"
59 
60 #include "DEG_depsgraph_physics.h"
61 #include "DEG_depsgraph_query.h"
62 
63 #include "MOD_ui_common.h"
64 #include "MOD_util.h"
65 
66 static void initData(ModifierData *md)
67 {
69 
70  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(clmd, modifier));
71 
75 
76  clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
77 
78  /* check for alloc failing */
79  if (!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache) {
80  return;
81  }
82 
83  if (!clmd->sim_parms->effector_weights) {
85  }
86 
87  if (clmd->point_cache) {
88  clmd->point_cache->step = 1;
89  }
90 }
91 
92 static void deformVerts(ModifierData *md,
93  const ModifierEvalContext *ctx,
94  Mesh *mesh,
95  float (*vertexCos)[3],
96  int numVerts)
97 {
98  Mesh *mesh_src;
101 
102  /* check for alloc failing */
103  if (!clmd->sim_parms || !clmd->coll_parms) {
104  initData(md);
105 
106  if (!clmd->sim_parms || !clmd->coll_parms) {
107  return;
108  }
109  }
110 
111  if (mesh == NULL) {
112  mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false);
113  }
114  else {
115  /* Not possible to use get_mesh() in this case as we'll modify its vertices
116  * and get_mesh() would return 'mesh' directly. */
117  mesh_src = (Mesh *)BKE_id_copy_ex(NULL, (ID *)mesh, NULL, LIB_ID_COPY_LOCALIZE);
118  }
119 
120  /* TODO(sergey): For now it actually duplicates logic from DerivedMesh.cc
121  * and needs some more generic solution. But starting experimenting with
122  * this so close to the release is not that nice..
123  *
124  * Also hopefully new cloth system will arrive soon..
125  */
126  if (mesh == NULL && clmd->sim_parms->shapekey_rest) {
128  clmd->sim_parms->shapekey_rest);
129  if (kb && kb->data != NULL) {
130  float(*layerorco)[3];
131  if (!(layerorco = CustomData_get_layer(&mesh_src->vdata, CD_CLOTH_ORCO))) {
132  layerorco = CustomData_add_layer(
133  &mesh_src->vdata, CD_CLOTH_ORCO, CD_CALLOC, NULL, mesh_src->totvert);
134  }
135 
136  memcpy(layerorco, kb->data, sizeof(float[3]) * numVerts);
137  }
138  }
139 
140  BKE_mesh_vert_coords_apply(mesh_src, vertexCos);
141 
142  clothModifier_do(clmd, ctx->depsgraph, scene, ctx->object, mesh_src, vertexCos);
143 
144  BKE_id_free(NULL, mesh_src);
145 }
146 
148 {
149  ClothModifierData *clmd = (ClothModifierData *)md;
150  if (clmd != NULL) {
153  ctx->object,
154  clmd->coll_parms->group,
156  NULL,
157  "Cloth Collision");
158  }
160  ctx->node, ctx->object, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
161  }
162  DEG_add_modifier_to_transform_relation(ctx->node, "Cloth Modifier");
163 }
164 
165 static void requiredDataMask(Object *UNUSED(ob),
166  ModifierData *md,
167  CustomData_MeshMasks *r_cddata_masks)
168 {
169  ClothModifierData *clmd = (ClothModifierData *)md;
170 
171  if (cloth_uses_vgroup(clmd)) {
172  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
173  }
174 
175  if (clmd->sim_parms->shapekey_rest != 0) {
176  r_cddata_masks->vmask |= CD_MASK_CLOTH_ORCO;
177  }
178 }
179 
180 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
181 {
182  const ClothModifierData *clmd = (const ClothModifierData *)md;
183  ClothModifierData *tclmd = (ClothModifierData *)target;
184 
185  if (tclmd->sim_parms) {
186  if (tclmd->sim_parms->effector_weights) {
188  }
189  MEM_freeN(tclmd->sim_parms);
190  }
191 
192  if (tclmd->coll_parms) {
193  MEM_freeN(tclmd->coll_parms);
194  }
195 
197  if (flag & LIB_ID_CREATE_NO_MAIN) {
198  /* Share the cache with the original object's modifier. */
200  tclmd->ptcaches = clmd->ptcaches;
201  tclmd->point_cache = clmd->point_cache;
202  }
203  else {
204  tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches);
205  if (clmd->point_cache != NULL) {
206  tclmd->point_cache->step = clmd->point_cache->step;
207  tclmd->point_cache->startframe = clmd->point_cache->startframe;
208  tclmd->point_cache->endframe = clmd->point_cache->endframe;
209  }
210  }
211 
212  tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
213  if (clmd->sim_parms->effector_weights) {
215  }
216  tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
217  tclmd->clothObject = NULL;
218  tclmd->hairdata = NULL;
219  tclmd->solver_result = NULL;
220 }
221 
223 {
224  return true;
225 }
226 
227 static void freeData(ModifierData *md)
228 {
229  ClothModifierData *clmd = (ClothModifierData *)md;
230 
231  if (clmd) {
232  if (G.debug & G_DEBUG_SIMDATA) {
233  printf("clothModifier_freeData\n");
234  }
235 
237 
238  if (clmd->sim_parms) {
239  if (clmd->sim_parms->effector_weights) {
241  }
242  MEM_freeN(clmd->sim_parms);
243  }
244  if (clmd->coll_parms) {
245  MEM_freeN(clmd->coll_parms);
246  }
247 
248  if (md->flag & eModifierFlag_SharedCaches) {
250  }
251  else {
253  }
254  clmd->point_cache = NULL;
255 
256  if (clmd->hairdata) {
257  MEM_freeN(clmd->hairdata);
258  }
259 
260  if (clmd->solver_result) {
261  MEM_freeN(clmd->solver_result);
262  }
263  }
264 }
265 
266 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
267 {
268  ClothModifierData *clmd = (ClothModifierData *)md;
269 
270  if (clmd->coll_parms) {
271  walk(userData, ob, (ID **)&clmd->coll_parms->group, IDWALK_CB_NOP);
272  }
273 
274  if (clmd->sim_parms && clmd->sim_parms->effector_weights) {
275  walk(userData, ob, (ID **)&clmd->sim_parms->effector_weights->group, IDWALK_CB_NOP);
276  }
277 }
278 
279 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
280 {
281  uiLayout *layout = panel->layout;
282 
284 
285  uiItemL(layout, IFACE_("Settings are inside the Physics tab"), ICON_NONE);
286 
287  modifier_panel_end(layout, ptr);
288 }
289 
290 static void panelRegister(ARegionType *region_type)
291 {
293 }
294 
296  /* name */ "Cloth",
297  /* structName */ "ClothModifierData",
298  /* structSize */ sizeof(ClothModifierData),
299  /* srna */ &RNA_ClothModifier,
300  /* type */ eModifierTypeType_OnlyDeform,
303  /* icon */ ICON_MOD_CLOTH,
304 
305  /* copyData */ copyData,
306 
307  /* deformVerts */ deformVerts,
308  /* deformMatrices */ NULL,
309  /* deformVertsEM */ NULL,
310  /* deformMatricesEM */ NULL,
311  /* modifyMesh */ NULL,
312  /* modifyHair */ NULL,
313  /* modifyGeometrySet */ NULL,
314  /* modifyVolume */ NULL,
315 
316  /* initData */ initData,
317  /* requiredDataMask */ requiredDataMask,
318  /* freeData */ freeData,
319  /* isDisabled */ NULL,
320  /* updateDepsgraph */ updateDepsgraph,
321  /* dependsOnTime */ dependsOnTime,
322  /* dependsOnNormals */ NULL,
323  /* foreachIDLink */ foreachIDLink,
324  /* foreachTexLink */ NULL,
325  /* freeRuntimeData */ NULL,
326  /* panelRegister */ panelRegister,
327  /* blendWrite */ NULL,
328  /* blendRead */ NULL,
329 };
typedef float(TangentPoint)[2]
int cloth_uses_vgroup(struct ClothModifierData *clmd)
Definition: cloth.c:611
void clothModifier_do(struct ClothModifierData *clmd, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct Mesh *me, float(*vertexCos)[3])
Definition: cloth.c:322
void cloth_free_modifier_extern(struct ClothModifierData *clmd)
Definition: cloth.c:505
@ 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.c:2620
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
Definition: effect.c:73
@ G_DEBUG_SIMDATA
Definition: BKE_global.h:150
struct KeyBlock * BKE_keyblock_from_key(struct Key *key, int index)
Definition: key.c:1926
struct Key * BKE_key_from_object(const struct Object *ob)
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:145
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:88
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag)
void BKE_id_free(struct Main *bmain, void *idv)
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:47
void BKE_mesh_vert_coords_apply(struct Mesh *mesh, const float(*vert_coords)[3])
Definition: mesh.c:1755
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:120
@ eModifierTypeFlag_Single
Definition: BKE_modifier.h:107
@ eModifierTypeFlag_UsesPointCache
Definition: BKE_modifier.h:104
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:80
@ eModifierTypeType_OnlyDeform
Definition: BKE_modifier.h:58
struct PointCache * BKE_ptcache_add(struct ListBase *ptcaches)
Definition: pointcache.c:3072
void BKE_ptcache_free_list(struct ListBase *ptcaches)
Definition: pointcache.c:3110
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
#define UNUSED(x)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define IFACE_(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:44
#define DNA_struct_default_alloc(struct_name)
Definition: DNA_defaults.h:47
@ eModifierFlag_SharedCaches
struct ClothModifierData ClothModifierData
@ eModifierType_Cloth
@ eModifierType_Collision
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
Definition: MOD_cloth.c:180
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
Definition: MOD_cloth.c:147
static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float(*vertexCos)[3], int numVerts)
Definition: MOD_cloth.c:92
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
Definition: MOD_cloth.c:266
static bool dependsOnTime(ModifierData *UNUSED(md))
Definition: MOD_cloth.c:222
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
Definition: MOD_cloth.c:279
static void initData(ModifierData *md)
Definition: MOD_cloth.c:66
static void panelRegister(ARegionType *region_type)
Definition: MOD_cloth.c:290
ModifierTypeInfo modifierType_Cloth
Definition: MOD_cloth.c:295
static void freeData(ModifierData *md)
Definition: MOD_cloth.c:227
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition: MOD_cloth.c:165
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
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 num_verts, const bool use_normals, const bool use_orco)
Definition: MOD_util.c:186
StructRNA RNA_ClothModifier
#define C
Definition: RandGen.cpp:39
void uiItemL(uiLayout *layout, const char *name, int icon)
Scene scene
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
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:273
void * data
Definition: DNA_key_types.h:66
int totvert
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:153
struct Object * object
Definition: BKE_modifier.h:154
struct DepsNodeHandle * node
Definition: BKE_modifier.h:147
struct uiLayout * layout
#define G(x, y, z)
PointerRNA * ptr
Definition: wm_files.c:3157