Blender V4.3
MOD_cloth.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstring>
10
11#include "BLI_utildefines.h"
12
13#include "BLI_listbase.h"
14
15#include "BLT_translation.hh"
16
17#include "DNA_cloth_types.h"
18#include "DNA_defaults.h"
19#include "DNA_key_types.h"
20#include "DNA_mesh_types.h"
22#include "DNA_object_types.h"
23#include "DNA_screen_types.h"
24
25#include "MEM_guardedalloc.h"
26
27#include "BKE_cloth.hh"
28#include "BKE_customdata.hh"
29#include "BKE_effect.h"
30#include "BKE_global.hh"
31#include "BKE_key.hh"
32#include "BKE_lib_id.hh"
33#include "BKE_lib_query.hh"
34#include "BKE_modifier.hh"
35#include "BKE_pointcache.h"
36
37#include "UI_interface.hh"
38#include "UI_resources.hh"
39
40#include "RNA_prototypes.hh"
41
44
45#include "MOD_ui_common.hh"
46
47static void init_data(ModifierData *md)
48{
50
52
56
57 clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
58
59 /* check for alloc failing */
60 if (!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache) {
61 return;
62 }
63
64 if (!clmd->sim_parms->effector_weights) {
66 }
67
68 if (clmd->point_cache) {
69 clmd->point_cache->step = 1;
70 }
71}
72
73static void deform_verts(ModifierData *md,
74 const ModifierEvalContext *ctx,
75 Mesh *mesh,
77{
80
81 /* check for alloc failing */
82 if (!clmd->sim_parms || !clmd->coll_parms) {
83 init_data(md);
84
85 if (!clmd->sim_parms || !clmd->coll_parms) {
86 return;
87 }
88 }
89
90 /* TODO(sergey): For now it actually duplicates logic from mesh_data_update.cc
91 * and needs some more generic solution. But starting experimenting with
92 * this so close to the release is not that nice..
93 *
94 * Also hopefully new cloth system will arrive soon..
95 */
96 if (mesh == nullptr && clmd->sim_parms->shapekey_rest) {
99 if (kb && kb->data != nullptr) {
100 float(*layerorco)[3];
101 if (!(layerorco = static_cast<float(*)[3]>(
102 CustomData_get_layer_for_write(&mesh->vert_data, CD_CLOTH_ORCO, mesh->verts_num))))
103 {
104 layerorco = static_cast<float(*)[3]>(CustomData_add_layer(
105 &mesh->vert_data, CD_CLOTH_ORCO, CD_SET_DEFAULT, mesh->verts_num));
106 }
107
108 memcpy(layerorco, kb->data, sizeof(float[3]) * positions.size());
109 }
110 }
111
112 mesh->vert_positions_for_write().copy_from(positions);
113 mesh->tag_positions_changed();
114
115 clothModifier_do(clmd,
116 ctx->depsgraph,
117 scene,
118 ctx->object,
119 mesh,
120 reinterpret_cast<float(*)[3]>(positions.data()));
121}
122
124{
126 if (clmd != nullptr) {
129 ctx->object,
130 clmd->coll_parms->group,
132 nullptr,
133 "Cloth Collision");
134 }
136 ctx->node, ctx->object, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
137 }
138 DEG_add_depends_on_transform_relation(ctx->node, "Cloth Modifier");
139}
140
141static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
142{
144
145 if (cloth_uses_vgroup(clmd)) {
146 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
147 }
148
149 if (clmd->sim_parms->shapekey_rest != 0) {
150 r_cddata_masks->vmask |= CD_MASK_CLOTH_ORCO;
151 }
152}
153
154static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
155{
156 const ClothModifierData *clmd = (const ClothModifierData *)md;
157 ClothModifierData *tclmd = (ClothModifierData *)target;
158
159 if (tclmd->sim_parms) {
160 if (tclmd->sim_parms->effector_weights) {
162 }
163 MEM_freeN(tclmd->sim_parms);
164 }
165
166 if (tclmd->coll_parms) {
167 MEM_freeN(tclmd->coll_parms);
168 }
169
172 /* Share the cache with the original object's modifier. */
174 tclmd->ptcaches = clmd->ptcaches;
175 tclmd->point_cache = clmd->point_cache;
176 }
177 else {
178 const int clmd_point_cache_index = BLI_findindex(&clmd->ptcaches, clmd->point_cache);
180 tclmd->point_cache = static_cast<PointCache *>(
181 BLI_findlink(&tclmd->ptcaches, clmd_point_cache_index));
182 }
183
184 tclmd->sim_parms = static_cast<ClothSimSettings *>(MEM_dupallocN(clmd->sim_parms));
185 if (clmd->sim_parms->effector_weights) {
186 tclmd->sim_parms->effector_weights = static_cast<EffectorWeights *>(
188 }
189 tclmd->coll_parms = static_cast<ClothCollSettings *>(MEM_dupallocN(clmd->coll_parms));
190 tclmd->clothObject = nullptr;
191 tclmd->hairdata = nullptr;
192 tclmd->solver_result = nullptr;
193}
194
195static bool depends_on_time(Scene * /*scene*/, ModifierData * /*md*/)
196{
197 return true;
198}
199
200static void free_data(ModifierData *md)
201{
203
204 if (clmd) {
205 if (G.debug & G_DEBUG_SIMDATA) {
206 printf("clothModifier_freeData\n");
207 }
208
210
211 if (clmd->sim_parms) {
212 if (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
223 }
224 else {
226 }
227 clmd->point_cache = nullptr;
228
229 if (clmd->hairdata) {
230 MEM_freeN(clmd->hairdata);
231 }
232
233 if (clmd->solver_result) {
235 }
236 }
237}
238
239static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
240{
242
243 if (clmd->coll_parms) {
244 walk(user_data, ob, (ID **)&clmd->coll_parms->group, IDWALK_CB_NOP);
245 }
246
247 if (clmd->sim_parms && clmd->sim_parms->effector_weights) {
248 walk(user_data, ob, (ID **)&clmd->sim_parms->effector_weights->group, IDWALK_CB_USER);
249 }
250}
251
252static void panel_draw(const bContext * /*C*/, Panel *panel)
253{
254 uiLayout *layout = panel->layout;
255
257
258 uiItemL(layout, RPT_("Settings are inside the Physics tab"), ICON_NONE);
259
260 modifier_panel_end(layout, ptr);
261}
262
263static void panel_register(ARegionType *region_type)
264{
266}
267
269 /*idname*/ "Cloth",
270 /*name*/ N_("Cloth"),
271 /*struct_name*/ "ClothModifierData",
272 /*struct_size*/ sizeof(ClothModifierData),
273 /*srna*/ &RNA_ClothModifier,
277 /*icon*/ ICON_MOD_CLOTH,
278
279 /*copy_data*/ copy_data,
280
281 /*deform_verts*/ deform_verts,
282 /*deform_matrices*/ nullptr,
283 /*deform_verts_EM*/ nullptr,
284 /*deform_matrices_EM*/ nullptr,
285 /*modify_mesh*/ nullptr,
286 /*modify_geometry_set*/ nullptr,
287
288 /*init_data*/ init_data,
289 /*required_data_mask*/ required_data_mask,
290 /*free_data*/ free_data,
291 /*is_disabled*/ nullptr,
292 /*update_depsgraph*/ update_depsgraph,
293 /*depends_on_time*/ depends_on_time,
294 /*depends_on_normals*/ nullptr,
295 /*foreach_ID_link*/ foreach_ID_link,
296 /*foreach_tex_link*/ nullptr,
297 /*free_runtime_data*/ nullptr,
298 /*panel_register*/ panel_register,
299 /*blend_write*/ nullptr,
300 /*blend_read*/ nullptr,
301 /*foreach_cache*/ nullptr,
302};
void clothModifier_do(ClothModifierData *clmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *mesh, float(*vertexCos)[3])
Definition cloth.cc:319
void cloth_free_modifier_extern(ClothModifierData *clmd)
Definition cloth.cc:494
int cloth_uses_vgroup(ClothModifierData *clmd)
Definition cloth.cc:587
CustomData interface, see also DNA_customdata_types.h.
@ CD_SET_DEFAULT
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
Definition effect.cc:57
@ G_DEBUG_SIMDATA
KeyBlock * BKE_keyblock_find_by_index(Key *key, int index)
Definition key.cc:1923
Key * BKE_key_from_object(Object *ob)
Definition key.cc:1820
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
@ IDWALK_CB_USER
@ IDWALK_CB_NOP
@ eModifierTypeFlag_Single
@ eModifierTypeFlag_UsesPointCache
@ eModifierTypeFlag_AcceptsMesh
void(*)(void *user_data, Object *ob, ID **idpoin, int cb_flag) IDWalkFunc
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)
void BKE_ptcache_free_list(struct ListBase *ptcaches)
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define RPT_(msgid)
void DEG_add_depends_on_transform_relation(DepsNodeHandle *node_handle, const char *description)
void DEG_add_collision_relations(DepsNodeHandle *handle, Object *object, Collection *collection, unsigned int modifier_type, DEG_CollobjFilterFunction filter_function, const char *name)
void DEG_add_forcefield_relations(DepsNodeHandle *handle, Object *object, EffectorWeights *eff, bool add_absorption, int skip_forcefield, const char *name)
Scene * DEG_get_evaluated_scene(const 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)
#define DNA_struct_default_alloc(struct_name)
@ 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 init_data(ModifierData *md)
Definition MOD_cloth.cc:47
static void deform_verts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
Definition MOD_cloth.cc:73
static void panel_register(ARegionType *region_type)
Definition MOD_cloth.cc:263
static void free_data(ModifierData *md)
Definition MOD_cloth.cc:200
static void panel_draw(const bContext *, Panel *panel)
Definition MOD_cloth.cc:252
static bool depends_on_time(Scene *, ModifierData *)
Definition MOD_cloth.cc:195
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition MOD_cloth.cc:141
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
Definition MOD_cloth.cc:239
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
Definition MOD_cloth.cc:123
ModifierTypeInfo modifierType_Cloth
Definition MOD_cloth.cc:268
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
Definition MOD_cloth.cc:154
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void uiItemL(uiLayout *layout, const char *name, int icon)
#define printf
draw_view in_light_buf[] float
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
#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:413
void * data
struct uiLayout * layout
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138