diff options
Diffstat (limited to 'source/blender/editors/object/object_modifier.c')
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 190 |
1 files changed, 135 insertions, 55 deletions
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 7cf24d5d07d..0ea1c00100a 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -42,6 +42,8 @@ #include "BLI_listbase.h" #include "BLI_string.h" #include "BLI_path_util.h" +#include "BLI_editVert.h" +#include "BLI_utildefines.h" #include "BKE_curve.h" #include "BKE_context.h" @@ -68,6 +70,7 @@ #include "ED_armature.h" #include "ED_object.h" #include "ED_screen.h" +#include "ED_mesh.h" #include "WM_api.h" #include "WM_types.h" @@ -76,18 +79,24 @@ /******************************** API ****************************/ -ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, 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; ModifierTypeInfo *mti = modifierType_getInfo(type); - + + /* only geometry objects should be able to get modifiers [#25291] */ + if(!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { + BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to Object '%s'", ob->id.name+2); + return NULL; + } + if(mti->flags&eModifierTypeFlag_Single) { if(modifiers_findByType(ob, type)) { BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed."); return NULL; } } - + if(type == eModifierType_ParticleSystem) { /* don't need to worry about the new modifier's name, since that is set to the number * of particle systems which shouldn't have too many duplicates @@ -132,9 +141,12 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc } else if(type == eModifierType_Surface) DAG_scene_sort(bmain, scene); + else if(type == eModifierType_Multires) + /* set totlvl from existing MDISPS layer if object already had it */ + multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob); } - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); return new_md; } @@ -189,14 +201,27 @@ int ED_object_modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Ob else if(md->type == eModifierType_Multires) { Mesh *me= ob->data; - CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface); - CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface); + if(me->edit_mesh) { + EditMesh *em= me->edit_mesh; + /* CustomData_external_remove is used here only to mark layer as non-external + for further free-ing, so zero element count looks safer than em->totface */ + CustomData_external_remove(&em->fdata, &me->id, CD_MDISPS, 0); + EM_free_data_layer(em, &em->fdata, CD_MDISPS); + } else { + CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface); + CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface); + } + } + + if(ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) && + ob->particlesystem.first == NULL) { + ob->mode &= ~OB_MODE_PARTICLE_EDIT; } BLI_remlink(&ob->modifiers, md); modifier_free(md); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sorting has to be done after the update so that dynamic systems can react properly */ if(sort_depsgraph) @@ -247,7 +272,7 @@ int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData * return 1; } -int ED_object_modifier_convert(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md) +int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md) { Object *obn; ParticleSystem *psys; @@ -362,7 +387,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes"); return 0; } - mesh_pmv_off(ob, me); + mesh_pmv_off(me); dm = mesh_create_derived_for_modifier(scene, ob, md); if (!dm) { @@ -410,7 +435,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, return 0; } - mesh_pmv_off(ob, me); + mesh_pmv_off(me); /* Multires: ensure that recent sculpting is applied */ if(md->type == eModifierType_Multires) @@ -431,6 +456,11 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, DM_to_mesh(dm, me); dm->release(dm); + + if(md->type == eModifierType_Multires) { + CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface); + CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface); + } } } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { @@ -452,7 +482,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, MEM_freeN(vertexCos); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } else { BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); @@ -503,7 +533,7 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi return 1; } -int ED_object_modifier_copy(ReportList *reports, Object *ob, ModifierData *md) +int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md) { ModifierData *nmd; @@ -532,7 +562,7 @@ static int modifier_add_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *ptr, int *free) +static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), int *free) { Object *ob= ED_object_active_context(C); EnumPropertyItem *item= NULL, *md_item; @@ -590,20 +620,21 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot) /************************ generic functions for operators using mod names and data context *********************/ -static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type) +static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag) { PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", rna_type); Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C); if (!ob || ob->id.lib) return 0; - if (ptr.data && ((ID*)ptr.id.data)->lib) return 0; + if (obtype_flag && ((1<<ob->type) & obtype_flag)==0) return 0; + if (ptr.id.data && ((ID*)ptr.id.data)->lib) return 0; return 1; } static int edit_modifier_poll(bContext *C) { - return edit_modifier_poll_generic(C, &RNA_Modifier); + return edit_modifier_poll_generic(C, &RNA_Modifier, 0); } static void edit_modifier_properties(wmOperatorType *ot) @@ -628,7 +659,7 @@ static int edit_modifier_invoke_properties(bContext *C, wmOperator *op) return 0; } -static ModifierData *edit_modifier_property_get(bContext *C, wmOperator *op, Object *ob, int type) +static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type) { char modifier_name[32]; ModifierData *md; @@ -649,17 +680,24 @@ static int modifier_remove_exec(bContext *C, wmOperator *op) Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob = ED_object_active_context(C); - ModifierData *md = edit_modifier_property_get(C, op, ob, 0); + ModifierData *md = edit_modifier_property_get(op, ob, 0); + int mode_orig = ob->mode; if(!ob || !md || !ED_object_modifier_remove(op->reports, bmain, scene, ob, md)) return OPERATOR_CANCELLED; WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + /* if cloth/softbody was removed, particle mode could be cleared */ + if(mode_orig & OB_MODE_PARTICLE_EDIT) + if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) + if(scene->basact && scene->basact->object==ob) + WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL); return OPERATOR_FINISHED; } -static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return modifier_remove_exec(C, op); @@ -687,18 +725,18 @@ void OBJECT_OT_modifier_remove(wmOperatorType *ot) static int modifier_move_up_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); - ModifierData *md = edit_modifier_property_get(C, op, ob, 0); + ModifierData *md = edit_modifier_property_get(op, ob, 0); if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md)) return OPERATOR_CANCELLED; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } -static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return modifier_move_up_exec(C, op); @@ -726,18 +764,18 @@ void OBJECT_OT_modifier_move_up(wmOperatorType *ot) static int modifier_move_down_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); - ModifierData *md = edit_modifier_property_get(C, op, ob, 0); + ModifierData *md = edit_modifier_property_get(op, ob, 0); if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md)) return OPERATOR_CANCELLED; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } -static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return modifier_move_down_exec(C, op); @@ -766,20 +804,20 @@ static int modifier_apply_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob = ED_object_active_context(C); - ModifierData *md = edit_modifier_property_get(C, op, ob, 0); + ModifierData *md = edit_modifier_property_get(op, ob, 0); int apply_as= RNA_enum_get(op->ptr, "apply_as"); if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) { return OPERATOR_CANCELLED; } - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } -static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return modifier_apply_exec(C, op); @@ -816,18 +854,18 @@ static int modifier_convert_exec(bContext *C, wmOperator *op) Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob = ED_object_active_context(C); - ModifierData *md = edit_modifier_property_get(C, op, ob, 0); + ModifierData *md = edit_modifier_property_get(op, ob, 0); if(!ob || !md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md)) return OPERATOR_CANCELLED; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } -static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return modifier_convert_exec(C, op); @@ -855,18 +893,18 @@ void OBJECT_OT_modifier_convert(wmOperatorType *ot) static int modifier_copy_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); - ModifierData *md = edit_modifier_property_get(C, op, ob, 0); + ModifierData *md = edit_modifier_property_get(op, ob, 0); if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md)) return OPERATOR_CANCELLED; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } -static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return modifier_copy_exec(C, op); @@ -893,13 +931,13 @@ void OBJECT_OT_modifier_copy(wmOperatorType *ot) static int multires_poll(bContext *C) { - return edit_modifier_poll_generic(C, &RNA_MultiresModifier); + return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1<<OB_MESH)); } static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); - MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Multires); + MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); if (!mmd) return OPERATOR_CANCELLED; @@ -911,7 +949,7 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return multires_higher_levels_delete_exec(C, op); @@ -938,20 +976,20 @@ void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot) static int multires_subdivide_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); - MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Multires); + MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); if (!mmd) return OPERATOR_CANCELLED; multiresModifier_subdivide(mmd, ob, 0, mmd->simple); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } -static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return multires_subdivide_exec(C, op); @@ -980,7 +1018,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) { Object *ob= ED_object_active_context(C), *secondob= NULL; Scene *scene= CTX_data_scene(C); - MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Multires); + MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); if (!mmd) return OPERATOR_CANCELLED; @@ -1003,13 +1041,13 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } -static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return multires_reshape_exec(C, op); @@ -1050,7 +1088,7 @@ static int multires_external_save_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "filepath", path); if(relative) - BLI_path_rel(path, G.sce); + BLI_path_rel(path, G.main->name); CustomData_external_add(&me->fdata, &me->id, CD_MDISPS, me->totface, path); CustomData_external_write(&me->fdata, &me->id, CD_MASK_MESH, me->totface, 0); @@ -1058,7 +1096,7 @@ static int multires_external_save_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { Object *ob = ED_object_active_context(C); MultiresModifierData *mmd; @@ -1068,7 +1106,7 @@ static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *e if (!edit_modifier_invoke_properties(C, op)) return OPERATOR_CANCELLED; - mmd = (MultiresModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Multires); + mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); if (!mmd) return OPERATOR_CANCELLED; @@ -1112,7 +1150,7 @@ void OBJECT_OT_multires_external_save(wmOperatorType *ot) /****************** multires pack operator *********************/ -static int multires_external_pack_exec(bContext *C, wmOperator *op) +static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_active_context(C); Mesh *me= ob->data; @@ -1139,18 +1177,60 @@ void OBJECT_OT_multires_external_pack(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/********************* multires apply base ***********************/ +static int multires_base_apply_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); + + if (!mmd) + return OPERATOR_CANCELLED; + + multiresModifier_base_apply(mmd, ob); + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int multires_base_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + if (edit_modifier_invoke_properties(C, op)) + return multires_base_apply_exec(C, op); + else + return OPERATOR_CANCELLED; +} + + +void OBJECT_OT_multires_base_apply(wmOperatorType *ot) +{ + ot->name= "Multires Apply Base"; + ot->description= "Modify the base mesh to conform to the displaced mesh"; + ot->idname= "OBJECT_OT_multires_base_apply"; + + ot->poll= multires_poll; + ot->invoke= multires_base_apply_invoke; + ot->exec= multires_base_apply_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); +} + + /************************ mdef bind operator *********************/ static int meshdeform_poll(bContext *C) { - return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier); + return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, (1<<OB_MESH)); } static int meshdeform_bind_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob = ED_object_active_context(C); - MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_MeshDeform); + MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform); if (!mmd) return OPERATOR_CANCELLED; @@ -1170,7 +1250,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) mmd->totcagevert= 0; mmd->totinfluence= 0; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); } else { @@ -1202,7 +1282,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return meshdeform_bind_exec(C, op); @@ -1231,26 +1311,26 @@ void OBJECT_OT_meshdeform_bind(wmOperatorType *ot) static int explode_poll(bContext *C) { - return edit_modifier_poll_generic(C, &RNA_ExplodeModifier); + return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0); } static int explode_refresh_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); - ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Explode); + ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(op, ob, eModifierType_Explode); if (!emd) return OPERATOR_CANCELLED; emd->flag |= eExplodeFlag_CalcFaces; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } -static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_modifier_invoke_properties(C, op)) return explode_refresh_exec(C, op); |