Blender  V3.3
MOD_fluid.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 <stddef.h>
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_task.h"
13 #include "BLI_utildefines.h"
14 
15 #include "BLT_translation.h"
16 
17 #include "DNA_collection_types.h"
18 #include "DNA_fluid_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 "BKE_context.h"
26 #include "BKE_fluid.h"
27 #include "BKE_layer.h"
28 #include "BKE_lib_query.h"
29 #include "BKE_modifier.h"
30 #include "BKE_screen.h"
31 
32 #include "UI_interface.h"
33 #include "UI_resources.h"
34 
35 #include "RNA_access.h"
36 #include "RNA_prototypes.h"
37 
38 #include "DEG_depsgraph.h"
39 #include "DEG_depsgraph_build.h"
40 #include "DEG_depsgraph_physics.h"
41 #include "DEG_depsgraph_query.h"
42 
43 #include "MOD_modifiertypes.h"
44 #include "MOD_ui_common.h"
45 
46 static void initData(ModifierData *md)
47 {
49 
50  fmd->domain = NULL;
51  fmd->flow = NULL;
52  fmd->effector = NULL;
53  fmd->type = 0;
54  fmd->time = -1;
55 }
56 
57 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
58 {
59 #ifndef WITH_FLUID
60  UNUSED_VARS(md, target, flag);
61 #else
62  const FluidModifierData *fmd = (const FluidModifierData *)md;
63  FluidModifierData *tfmd = (FluidModifierData *)target;
64 
66  BKE_fluid_modifier_copy(fmd, tfmd, flag);
67 #endif /* WITH_FLUID */
68 }
69 
70 static void freeData(ModifierData *md)
71 {
72 #ifndef WITH_FLUID
73  UNUSED_VARS(md);
74 #else
76 
78 #endif /* WITH_FLUID */
79 }
80 
81 static void requiredDataMask(Object *UNUSED(ob),
82  ModifierData *md,
83  CustomData_MeshMasks *r_cddata_masks)
84 {
86 
87  if (fmd && (fmd->type & MOD_FLUID_TYPE_FLOW) && fmd->flow) {
88  if (fmd->flow->source == FLUID_FLOW_SOURCE_MESH) {
89  /* vertex groups */
90  if (fmd->flow->vgroup_density) {
91  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
92  }
93  /* uv layer */
95  r_cddata_masks->fmask |= CD_MASK_MTFACE;
96  }
97  }
98  }
99 }
100 
101 typedef struct FluidIsolationData {
106 
109 
110 #ifdef WITH_FLUID
111 static void fluid_modifier_do_isolated(void *userdata)
112 {
113  FluidIsolationData *isolation_data = (FluidIsolationData *)userdata;
114 
115  Scene *scene = DEG_get_evaluated_scene(isolation_data->depsgraph);
116 
117  Mesh *result = BKE_fluid_modifier_do(isolation_data->fmd,
118  isolation_data->depsgraph,
119  scene,
120  isolation_data->object,
121  isolation_data->mesh);
122  isolation_data->result = result ? result : isolation_data->mesh;
123 }
124 #endif /* WITH_FLUID */
125 
126 static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *me)
127 {
128 #ifndef WITH_FLUID
129  UNUSED_VARS(md, ctx);
130  return me;
131 #else
133 
134  if (ctx->flag & MOD_APPLY_ORCO) {
135  return me;
136  }
137 
138  /* Isolate execution of Mantaflow when running from dependency graph. The reason for this is
139  * because Mantaflow uses TBB to parallel its own computation which without isolation will start
140  * stealing tasks from dependency graph. Stealing tasks from the dependency graph might cause
141  * a recursive lock when Python drivers are used (because Mantaflow is interfaced via Python as
142  * well. */
143  FluidIsolationData isolation_data;
144  isolation_data.depsgraph = ctx->depsgraph;
145  isolation_data.object = ctx->object;
146  isolation_data.mesh = me;
147  isolation_data.fmd = fmd;
148  BLI_task_isolate(fluid_modifier_do_isolated, &isolation_data);
149 
150  return isolation_data.result;
151 #endif /* WITH_FLUID */
152 }
153 
154 static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *UNUSED(md))
155 {
156  return true;
157 }
158 
159 static bool is_flow_cb(Object *UNUSED(ob), ModifierData *md)
160 {
162  return (fmd->type & MOD_FLUID_TYPE_FLOW) && fmd->flow;
163 }
164 
165 static bool is_coll_cb(Object *UNUSED(ob), ModifierData *md)
166 {
168  return (fmd->type & MOD_FLUID_TYPE_EFFEC) && fmd->effector;
169 }
170 
172 {
174 
175  if (fmd && (fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
177  ctx->object,
178  fmd->domain->fluid_group,
180  is_flow_cb,
181  "Fluid Flow");
183  ctx->object,
184  fmd->domain->effector_group,
186  is_coll_cb,
187  "Fluid Effector");
189  ctx->object,
190  fmd->domain->effector_weights,
191  true,
193  "Fluid Force Field");
194 
195  if (fmd->domain->guide_parent != NULL) {
197  ctx->node, fmd->domain->guide_parent, DEG_OB_COMP_TRANSFORM, "Fluid Guiding Object");
199  ctx->node, fmd->domain->guide_parent, DEG_OB_COMP_GEOMETRY, "Fluid Guiding Object");
200  }
201  }
202 }
203 
204 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
205 {
207 
208  if (fmd->type == MOD_FLUID_TYPE_DOMAIN && fmd->domain) {
209  walk(userData, ob, (ID **)&fmd->domain->effector_group, IDWALK_CB_NOP);
210  walk(userData, ob, (ID **)&fmd->domain->fluid_group, IDWALK_CB_NOP);
211  walk(userData, ob, (ID **)&fmd->domain->force_group, IDWALK_CB_NOP);
212 
213  if (fmd->domain->guide_parent) {
214  walk(userData, ob, (ID **)&fmd->domain->guide_parent, IDWALK_CB_NOP);
215  }
216 
217  if (fmd->domain->effector_weights) {
218  walk(userData, ob, (ID **)&fmd->domain->effector_weights->group, IDWALK_CB_USER);
219  }
220  }
221 
222  if (fmd->type == MOD_FLUID_TYPE_FLOW && fmd->flow) {
223  walk(userData, ob, (ID **)&fmd->flow->noise_texture, IDWALK_CB_USER);
224  }
225 }
226 
227 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
228 {
229  uiLayout *layout = panel->layout;
230 
232 
233  uiItemL(layout, TIP_("Settings are inside the Physics tab"), ICON_NONE);
234 
235  modifier_panel_end(layout, ptr);
236 }
237 
238 static void panelRegister(ARegionType *region_type)
239 {
241 }
242 
244  /* name */ N_("Fluid"),
245  /* structName */ "FluidModifierData",
246  /* structSize */ sizeof(FluidModifierData),
247  /* srna */ &RNA_FluidModifier,
250  /* icon */ ICON_MOD_FLUIDSIM,
251 
252  /* copyData */ copyData,
253 
254  /* deformVerts */ NULL,
255  /* deformMatrices */ NULL,
256  /* deformVertsEM */ NULL,
257  /* deformMatricesEM */ NULL,
258  /* modifyMesh */ modifyMesh,
259  /* modifyGeometrySet */ NULL,
260 
261  /* initData */ initData,
262  /* requiredDataMask */ requiredDataMask,
263  /* freeData */ freeData,
264  /* isDisabled */ NULL,
265  /* updateDepsgraph */ updateDepsgraph,
266  /* dependsOnTime */ dependsOnTime,
267  /* dependsOnNormals */ NULL,
268  /* foreachIDLink */ foreachIDLink,
269  /* foreachTexLink */ NULL,
270  /* freeRuntimeData */ NULL,
271  /* panelRegister */ panelRegister,
272  /* blendWrite */ NULL,
273  /* blendRead */ NULL,
274 };
void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd, struct FluidModifierData *tfmd, int flag)
Definition: fluid.c:4865
struct Mesh * BKE_fluid_modifier_do(struct FluidModifierData *fmd, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct Mesh *me)
void BKE_fluid_modifier_free(struct FluidModifierData *fmd)
Definition: fluid.c:4798
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
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_AcceptsMesh
Definition: BKE_modifier.h:66
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:47
@ MOD_APPLY_ORCO
Definition: BKE_modifier.h:120
void BLI_task_isolate(void(*func)(void *userdata), void *userdata)
#define UNUSED_VARS(...)
#define UNUSED(x)
#define TIP_(msgid)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_add_object_relation(struct DepsNodeHandle *node_handle, struct Object *object, eDepsObjectComponentType component, const char *description)
@ DEG_OB_COMP_GEOMETRY
@ DEG_OB_COMP_TRANSFORM
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)
Object groups, one object can be in many groups at once.
#define CD_MASK_MDEFORMVERT
#define CD_MASK_MTFACE
@ FLUID_FLOW_SOURCE_MESH
@ FLUID_FLOW_TEXTURE_MAP_UV
struct FluidModifierData FluidModifierData
@ eModifierType_Fluid
@ MOD_FLUID_TYPE_EFFEC
@ MOD_FLUID_TYPE_DOMAIN
@ MOD_FLUID_TYPE_FLOW
@ PFIELD_FLUIDFLOW
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_fluid.c:154
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
Definition: MOD_fluid.c:57
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
Definition: MOD_fluid.c:171
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *me)
Definition: MOD_fluid.c:126
static bool is_coll_cb(Object *UNUSED(ob), ModifierData *md)
Definition: MOD_fluid.c:165
static bool is_flow_cb(Object *UNUSED(ob), ModifierData *md)
Definition: MOD_fluid.c:159
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
Definition: MOD_fluid.c:204
ModifierTypeInfo modifierType_Fluid
Definition: MOD_fluid.c:243
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
Definition: MOD_fluid.c:227
static void initData(ModifierData *md)
Definition: MOD_fluid.c:46
static void panelRegister(ARegionType *region_type)
Definition: MOD_fluid.c:238
struct FluidIsolationData FluidIsolationData
static void freeData(ModifierData *md)
Definition: MOD_fluid.c:70
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition: MOD_fluid.c:81
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)
#define C
Definition: RandGen.cpp:25
void uiItemL(uiLayout *layout, const char *name, int icon)
Scene scene
struct Collection * group
struct Collection * force_group
struct Collection * effector_group
struct Object * guide_parent
struct Collection * fluid_group
struct EffectorWeights * effector_weights
struct Tex * noise_texture
FluidModifierData * fmd
Definition: MOD_fluid.c:105
Depsgraph * depsgraph
Definition: MOD_fluid.c:102
struct FluidDomainSettings * domain
struct FluidEffectorSettings * effector
struct FluidFlowSettings * flow
Definition: DNA_ID.h:368
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:140
ModifierApplyFlag flag
Definition: BKE_modifier.h:142
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