Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/object/object_modifier.c
| Show First 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | |||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "object_intern.h" | #include "object_intern.h" | ||||
| static void modifier_skin_customdata_delete(struct Object *ob); | static void modifier_skin_customdata_delete(struct Object *ob); | ||||
| /******************************** API ****************************/ | /******************************** API ****************************/ | ||||
| static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Scene *scene, Object *ob) | static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *ob) | ||||
| { | { | ||||
| Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); | |||||
| Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); | |||||
| BKE_object_eval_reset(ob_eval); | |||||
| if (ob->type == OB_MESH) { | if (ob->type == OB_MESH) { | ||||
| Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene, ob, &CD_MASK_BAREMESH); | Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH); | ||||
| BKE_id_free(NULL, me_eval); | BKE_id_free(NULL, me_eval); | ||||
| } | } | ||||
| else if (ob->type == OB_LATTICE) { | else if (ob->type == OB_LATTICE) { | ||||
| BKE_lattice_modifiers_calc(depsgraph, scene, ob); | BKE_lattice_modifiers_calc(depsgraph, scene_eval, ob_eval); | ||||
| } | } | ||||
| else if (ob->type == OB_MBALL) { | else if (ob->type == OB_MBALL) { | ||||
| BKE_displist_make_mball(depsgraph, scene, ob); | BKE_displist_make_mball(depsgraph, scene_eval, ob_eval); | ||||
| } | } | ||||
| else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { | else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { | ||||
| BKE_displist_make_curveTypes(depsgraph, scene, ob, false, false, NULL); | BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false, false, NULL); | ||||
| } | } | ||||
| } | } | ||||
| static void object_force_modifier_bind_simple_options( | |||||
| Depsgraph *depsgraph, | |||||
| Object *object, | |||||
| ModifierData *md) | |||||
| { | |||||
| ModifierData *md_eval = (ModifierData *)modifier_get_evaluated(depsgraph, object, md); | |||||
| const int mode = md_eval->mode; | |||||
| md_eval->mode |= eModifierMode_Realtime; | |||||
| object_force_modifier_update_for_bind(depsgraph, object); | |||||
| md_eval->mode = mode; | |||||
| } | |||||
| ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type) | ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type) | ||||
| { | { | ||||
| ModifierData *md = NULL, *new_md = NULL; | ModifierData *md = NULL, *new_md = NULL; | ||||
| const ModifierTypeInfo *mti = modifierType_getInfo(type); | const ModifierTypeInfo *mti = modifierType_getInfo(type); | ||||
| /* Check compatibility of modifier [T25291, T50373]. */ | /* Check compatibility of modifier [T25291, T50373]. */ | ||||
| if (!BKE_object_support_modifier_type_check(ob, type)) { | if (!BKE_object_support_modifier_type_check(ob, type)) { | ||||
| BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2); | BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2); | ||||
| ▲ Show 20 Lines • Show All 1,800 Lines • ▼ Show 20 Lines | static int correctivesmooth_bind_exec(bContext *C, wmOperator *op) | ||||
| MEM_SAFE_FREE(csmd->bind_coords); | MEM_SAFE_FREE(csmd->bind_coords); | ||||
| MEM_SAFE_FREE(csmd->delta_cache); | MEM_SAFE_FREE(csmd->delta_cache); | ||||
| if (is_bind) { | if (is_bind) { | ||||
| /* toggle off */ | /* toggle off */ | ||||
| csmd->bind_coords_num = 0; | csmd->bind_coords_num = 0; | ||||
| } | } | ||||
| else { | else { | ||||
| /* signal to modifier to recalculate */ | /* Signal to modifier to recalculate. */ | ||||
| csmd->bind_coords_num = (unsigned int)-1; | CorrectiveSmoothModifierData *csmd_eval = | ||||
| (CorrectiveSmoothModifierData *)modifier_get_evaluated(depsgraph, ob, &csmd->modifier); | |||||
| csmd_eval->bind_coords_num = (unsigned int)-1; | |||||
| /* Force modifier to run, it will call binding routine | /* Force modifier to run, it will call binding routine | ||||
| * (this has to happen outside of depsgraph evaluation). */ | * (this has to happen outside of depsgraph evaluation). */ | ||||
| const int mode = csmd->modifier.mode; | object_force_modifier_bind_simple_options(depsgraph, ob, &csmd->modifier); | ||||
| csmd->modifier.mode |= eModifierMode_Realtime; | |||||
| object_force_modifier_update_for_bind(depsgraph, scene, ob); | |||||
| csmd->modifier.mode = mode; | |||||
| } | } | ||||
| /* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */ | DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); | ||||
| DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int correctivesmooth_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | static int correctivesmooth_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| if (edit_modifier_invoke_properties(C, op)) | if (edit_modifier_invoke_properties(C, op)) | ||||
| Show All 24 Lines | |||||
| static bool meshdeform_poll(bContext *C) | static bool meshdeform_poll(bContext *C) | ||||
| { | { | ||||
| return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, 0); | return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, 0); | ||||
| } | } | ||||
| static int meshdeform_bind_exec(bContext *C, wmOperator *op) | static int meshdeform_bind_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | Depsgraph *depsgraph = CTX_data_depsgraph(C); | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| Object *ob = ED_object_active_context(C); | Object *ob = ED_object_active_context(C); | ||||
| MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform); | MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform); | ||||
| if (mmd == NULL) { | if (mmd == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (mmd->bindcagecos != NULL) { | if (mmd->bindcagecos != NULL) { | ||||
| MEM_SAFE_FREE(mmd->bindcagecos); | MEM_SAFE_FREE(mmd->bindcagecos); | ||||
| MEM_SAFE_FREE(mmd->dyngrid); | MEM_SAFE_FREE(mmd->dyngrid); | ||||
| MEM_SAFE_FREE(mmd->dyninfluences); | MEM_SAFE_FREE(mmd->dyninfluences); | ||||
| MEM_SAFE_FREE(mmd->bindinfluences); | MEM_SAFE_FREE(mmd->bindinfluences); | ||||
| MEM_SAFE_FREE(mmd->bindoffsets); | MEM_SAFE_FREE(mmd->bindoffsets); | ||||
| MEM_SAFE_FREE(mmd->dynverts); | MEM_SAFE_FREE(mmd->dynverts); | ||||
| MEM_SAFE_FREE(mmd->bindweights); /* Deprecated */ | MEM_SAFE_FREE(mmd->bindweights); /* Deprecated */ | ||||
| MEM_SAFE_FREE(mmd->bindcos); /* Deprecated */ | MEM_SAFE_FREE(mmd->bindcos); /* Deprecated */ | ||||
| mmd->totvert = 0; | mmd->totvert = 0; | ||||
| mmd->totcagevert = 0; | mmd->totcagevert = 0; | ||||
| mmd->totinfluence = 0; | mmd->totinfluence = 0; | ||||
| } | } | ||||
| else { | else { | ||||
| /* Force modifier to run, it will call binding routine (this has to happen outside of depsgraph evaluation). */ | /* Force modifier to run, it will call binding routine (this has to happen outside of depsgraph evaluation). */ | ||||
| const int mode = mmd->modifier.mode; | MeshDeformModifierData *mmd_eval = | ||||
| mmd->modifier.mode |= eModifierMode_Realtime; | (MeshDeformModifierData *)modifier_get_evaluated(depsgraph, ob, &mmd->modifier); | ||||
| mmd->bindfunc = ED_mesh_deform_bind_callback; | mmd_eval->bindfunc = ED_mesh_deform_bind_callback; | ||||
| object_force_modifier_update_for_bind(depsgraph, scene, ob); | object_force_modifier_bind_simple_options(depsgraph, ob, &mmd->modifier); | ||||
| mmd->modifier.mode = mode; | mmd_eval->bindfunc = NULL; | ||||
| mmd->bindfunc = NULL; | |||||
| } | } | ||||
| /* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */ | DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); | ||||
| DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| if (edit_modifier_invoke_properties(C, op)) | if (edit_modifier_invoke_properties(C, op)) | ||||
| return meshdeform_bind_exec(C, op); | return meshdeform_bind_exec(C, op); | ||||
| ▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | static int ocean_bake_exec(bContext *C, wmOperator *op) | ||||
| wmJob *wm_job; | wmJob *wm_job; | ||||
| OceanBakeJob *oj; | OceanBakeJob *oj; | ||||
| if (!omd) | if (!omd) | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| if (free) { | if (free) { | ||||
| BKE_ocean_free_modifier_cache(omd); | BKE_ocean_free_modifier_cache(omd); | ||||
| DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); | DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); | ||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| och = BKE_ocean_init_cache( | och = BKE_ocean_init_cache( | ||||
| omd->cachepath, modifier_path_relbase(bmain, ob), | omd->cachepath, modifier_path_relbase(bmain, ob), | ||||
| omd->bakestart, omd->bakeend, omd->wave_scale, | omd->bakestart, omd->bakeend, omd->wave_scale, | ||||
| omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution); | omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution); | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | |||||
| static bool laplaciandeform_poll(bContext *C) | static bool laplaciandeform_poll(bContext *C) | ||||
| { | { | ||||
| return edit_modifier_poll_generic(C, &RNA_LaplacianDeformModifier, 0); | return edit_modifier_poll_generic(C, &RNA_LaplacianDeformModifier, 0); | ||||
| } | } | ||||
| static int laplaciandeform_bind_exec(bContext *C, wmOperator *op) | static int laplaciandeform_bind_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| Object *ob = ED_object_active_context(C); | Object *ob = ED_object_active_context(C); | ||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | Depsgraph *depsgraph = CTX_data_depsgraph(C); | ||||
| LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_LaplacianDeform); | LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_LaplacianDeform); | ||||
| if (lmd == NULL) { | if (lmd == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (lmd->flag & MOD_LAPLACIANDEFORM_BIND) { | if (lmd->flag & MOD_LAPLACIANDEFORM_BIND) { | ||||
| lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND; | lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND; | ||||
| } | } | ||||
| else { | else { | ||||
| lmd->flag |= MOD_LAPLACIANDEFORM_BIND; | lmd->flag |= MOD_LAPLACIANDEFORM_BIND; | ||||
| } | } | ||||
| LaplacianDeformModifierData *lmd_eval = | |||||
| (LaplacianDeformModifierData *)modifier_get_evaluated(depsgraph, ob, &lmd->modifier); | |||||
| lmd_eval->flag = lmd->flag; | |||||
| /* Force modifier to run, it will call binding routine | /* Force modifier to run, it will call binding routine | ||||
| * (this has to happen outside of depsgraph evaluation). */ | * (this has to happen outside of depsgraph evaluation). */ | ||||
| const int mode = lmd->modifier.mode; | object_force_modifier_bind_simple_options(depsgraph, ob, &lmd->modifier); | ||||
| lmd->modifier.mode |= eModifierMode_Realtime; | |||||
| object_force_modifier_update_for_bind(depsgraph, scene, ob); | |||||
| lmd->modifier.mode = mode; | |||||
| /* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */ | /* This is hard to know from the modifier itself whether the evaluation is | ||||
| DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); | * happening for binding or not. So we copy all the required data here. */ | ||||
| lmd->total_verts = lmd_eval->total_verts; | |||||
| if (lmd_eval->vertexco == NULL) { | |||||
| MEM_SAFE_FREE(lmd->vertexco); | |||||
brecht: Not needed, already NULL. | |||||
| } | |||||
| else { | |||||
| lmd->vertexco = MEM_dupallocN(lmd_eval->vertexco); | |||||
| } | |||||
| DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | static int laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| if (edit_modifier_invoke_properties(C, op)) | if (edit_modifier_invoke_properties(C, op)) | ||||
| return laplaciandeform_bind_exec(C, op); | return laplaciandeform_bind_exec(C, op); | ||||
| Show All 22 Lines | |||||
| static bool surfacedeform_bind_poll(bContext *C) | static bool surfacedeform_bind_poll(bContext *C) | ||||
| { | { | ||||
| return edit_modifier_poll_generic(C, &RNA_SurfaceDeformModifier, 0); | return edit_modifier_poll_generic(C, &RNA_SurfaceDeformModifier, 0); | ||||
| } | } | ||||
| static int surfacedeform_bind_exec(bContext *C, wmOperator *op) | static int surfacedeform_bind_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| Object *ob = ED_object_active_context(C); | Object *ob = ED_object_active_context(C); | ||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | Depsgraph *depsgraph = CTX_data_depsgraph(C); | ||||
| SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_SurfaceDeform); | SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_SurfaceDeform); | ||||
| if (smd == NULL) { | if (smd == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (smd->flags & MOD_SDEF_BIND) { | if (smd->flags & MOD_SDEF_BIND) { | ||||
| smd->flags &= ~MOD_SDEF_BIND; | smd->flags &= ~MOD_SDEF_BIND; | ||||
| } | } | ||||
| else if (smd->target) { | else if (smd->target) { | ||||
| smd->flags |= MOD_SDEF_BIND; | smd->flags |= MOD_SDEF_BIND; | ||||
| } | } | ||||
| SurfaceDeformModifierData *smd_eval = | |||||
| (SurfaceDeformModifierData *)modifier_get_evaluated(depsgraph, ob, &smd->modifier); | |||||
| smd_eval->flags = smd->flags; | |||||
| /* Force modifier to run, it will call binding routine | /* Force modifier to run, it will call binding routine | ||||
| * (this has to happen outside of depsgraph evaluation). */ | * (this has to happen outside of depsgraph evaluation). */ | ||||
| const int mode = smd->modifier.mode; | object_force_modifier_bind_simple_options(depsgraph, ob, &smd->modifier); | ||||
| smd->modifier.mode |= eModifierMode_Realtime; | |||||
| object_force_modifier_update_for_bind(depsgraph, scene, ob); | |||||
| smd->modifier.mode = mode; | |||||
| /* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */ | DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); | ||||
| DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | static int surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| if (edit_modifier_invoke_properties(C, op)) | if (edit_modifier_invoke_properties(C, op)) | ||||
| return surfacedeform_bind_exec(C, op); | return surfacedeform_bind_exec(C, op); | ||||
| Show All 20 Lines | |||||
Not needed, already NULL.