diff options
Diffstat (limited to 'source/blender/editors/object/object_modifier.c')
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 220 |
1 files changed, 183 insertions, 37 deletions
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 0de2f114b94..9398a5f2ce7 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -86,6 +86,7 @@ #include "ED_mesh.h" #include "ED_object.h" #include "ED_screen.h" +#include "ED_sculpt.h" #include "WM_api.h" #include "WM_types.h" @@ -134,23 +135,24 @@ static void object_force_modifier_bind_simple_options(Depsgraph *depsgraph, Object *object, ModifierData *md) { - ModifierData *md_eval = (ModifierData *)modifier_get_evaluated(depsgraph, object, md); + ModifierData *md_eval = (ModifierData *)BKE_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; } -/** Add a modifier to given object, including relevant extra processing needed by some physics - * types (particles, simulations...). +/** + * Add a modifier to given object, including relevant extra processing needed by some physics types + * (particles, simulations...). * - * \param scene is only used to set current frame in some cases, and may be NULL. + * \param scene: is only used to set current frame in some cases, and may be NULL. */ ModifierData *ED_object_modifier_add( ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type) { ModifierData *md = NULL, *new_md = NULL; - const ModifierTypeInfo *mti = modifierType_getInfo(type); + const ModifierTypeInfo *mti = BKE_modifier_get_info(type); /* Check compatibility of modifier [T25291, T50373]. */ if (!BKE_object_support_modifier_type_check(ob, type)) { @@ -159,7 +161,7 @@ ModifierData *ED_object_modifier_add( } if (mti->flags & eModifierTypeFlag_Single) { - if (modifiers_findByType(ob, type)) { + if (BKE_modifiers_findby_type(ob, type)) { BKE_report(reports, RPT_WARNING, "Only one modifier of this type is allowed"); return NULL; } @@ -173,12 +175,12 @@ ModifierData *ED_object_modifier_add( } else { /* get new modifier data to add */ - new_md = modifier_new(type); + new_md = BKE_modifier_new(type); if (mti->flags & eModifierTypeFlag_RequiresOriginalData) { md = ob->modifiers.first; - while (md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform) { + while (md && BKE_modifier_get_info(md->type)->type == eModifierTypeType_OnlyDeform) { md = md->next; } @@ -194,7 +196,7 @@ ModifierData *ED_object_modifier_add( /* make sure modifier data has unique name */ - modifier_unique_name(&ob->modifiers, new_md); + BKE_modifier_unique_name(&ob->modifiers, new_md); /* special cases */ if (type == eModifierType_Softbody) { @@ -381,7 +383,7 @@ static bool object_modifier_remove(Main *bmain, } BLI_remlink(&ob->modifiers, md); - modifier_free(md); + BKE_modifier_free(md); BKE_object_free_derived_caches(ob); return 1; @@ -431,10 +433,10 @@ void ED_object_modifier_clear(Main *bmain, Object *ob) int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md) { if (md->prev) { - const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); if (mti->type != eModifierTypeType_OnlyDeform) { - const ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type); + const ModifierTypeInfo *nmti = BKE_modifier_get_info(md->prev->type); if (nmti->flags & eModifierTypeFlag_RequiresOriginalData) { BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data"); @@ -452,10 +454,10 @@ int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md) { if (md->next) { - const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); if (mti->flags & eModifierTypeFlag_RequiresOriginalData) { - const ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type); + const ModifierTypeInfo *nmti = BKE_modifier_get_info(md->next->type); if (nmti->type != eModifierTypeType_OnlyDeform) { BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier"); @@ -618,7 +620,7 @@ static int modifier_apply_shape(Main *bmain, Object *ob, ModifierData *md_eval) { - const ModifierTypeInfo *mti = modifierType_getInfo(md_eval->type); + const ModifierTypeInfo *mti = BKE_modifier_get_info(md_eval->type); if (mti->isDisabled && mti->isDisabled(scene, md_eval, 0)) { BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply"); @@ -642,7 +644,7 @@ static int modifier_apply_shape(Main *bmain, Key *key = me->key; KeyBlock *kb; - if (!modifier_isSameTopology(md_eval) || mti->type == eModifierTypeType_NonGeometrical) { + if (!BKE_modifier_is_same_topology(md_eval) || mti->type == eModifierTypeType_NonGeometrical) { BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes"); return 0; } @@ -678,7 +680,7 @@ static int modifier_apply_shape(Main *bmain, static int modifier_apply_obdata( ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md_eval) { - const ModifierTypeInfo *mti = modifierType_getInfo(md_eval->type); + const ModifierTypeInfo *mti = BKE_modifier_get_info(md_eval->type); if (mti->isDisabled && mti->isDisabled(scene, md_eval, 0)) { BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply"); @@ -789,7 +791,7 @@ bool ED_object_modifier_apply(Main *bmain, return false; } else if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) && - (modifier_isSameTopology(md) == false)) { + (BKE_modifier_is_same_topology(md) == false)) { BKE_report(reports, RPT_ERROR, "Constructive modifier cannot be applied to multi-res data in sculpt mode"); @@ -803,7 +805,7 @@ bool ED_object_modifier_apply(Main *bmain, /* Get evaluated modifier, so object links pointer to evaluated data, * but still use original object it is applied to the original mesh. */ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); - ModifierData *md_eval = (ob_eval) ? modifiers_findByName(ob_eval, md->name) : md; + ModifierData *md_eval = (ob_eval) ? BKE_modifiers_findby_name(ob_eval, md->name) : md; /* allow apply of a not-realtime modifier, by first re-enabling realtime. */ prev_mode = md_eval->mode; @@ -824,7 +826,7 @@ bool ED_object_modifier_apply(Main *bmain, md_eval->mode = prev_mode; BLI_remlink(&ob->modifiers, md); - modifier_free(md); + BKE_modifier_free(md); BKE_object_free_derived_caches(ob); @@ -835,10 +837,10 @@ int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierDat { ModifierData *nmd; - nmd = modifier_new(md->type); - modifier_copyData(md, nmd); + nmd = BKE_modifier_new(md->type); + BKE_modifier_copydata(md, nmd); BLI_insertlinkafter(&ob->modifiers, md, nmd); - modifier_unique_name(&ob->modifiers, nmd); + BKE_modifier_unique_name(&ob->modifiers, nmd); return 1; } @@ -884,7 +886,7 @@ static const EnumPropertyItem *modifier_add_itemf(bContext *C, md_item = &rna_enum_object_modifier_type_items[a]; if (md_item->identifier[0]) { - mti = modifierType_getInfo(md_item->value); + mti = BKE_modifier_get_info(md_item->value); if (mti->flags & eModifierTypeFlag_NoUserAdd) { continue; @@ -1018,7 +1020,7 @@ ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type) ModifierData *md; RNA_string_get(op->ptr, "modifier", modifier_name); - md = modifiers_findByName(ob, modifier_name); + md = BKE_modifiers_findby_name(ob, modifier_name); if (md && type != 0 && md->type != type) { md = NULL; @@ -1198,7 +1200,7 @@ static bool modifier_apply_poll(bContext *C) } else if (md != NULL) { if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) && - (modifier_isSameTopology(md) == false)) { + (BKE_modifier_is_same_topology(md) == false)) { CTX_wm_operator_poll_msg_set( C, "Constructive modifier cannot be applied to multi-res data in sculpt mode"); return false; @@ -1431,6 +1433,25 @@ void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot) /** \name Multires Subdivide Operator * \{ */ +static EnumPropertyItem prop_multires_subdivide_mode_type[] = { + {MULTIRES_SUBDIVIDE_CATMULL_CLARK, + "CATMULL_CLARK", + 0, + "Catmull-Clark", + "Create a new level using Catmull-Clark subdivisions"}, + {MULTIRES_SUBDIVIDE_SIMPLE, + "SIMPLE", + 0, + "Simple", + "Create a new level using simple subdivisions"}, + {MULTIRES_SUBDIVIDE_LINEAR, + "LINEAR", + 0, + "Linear", + "Create a new level using linear interpolation of the sculpted displacement"}, + {0, NULL, 0, NULL, NULL}, +}; + static int multires_subdivide_exec(bContext *C, wmOperator *op) { Object *object = ED_object_active_context(C); @@ -1441,7 +1462,9 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - multiresModifier_subdivide(object, mmd); + const eMultiresSubdivideModeType subdivide_mode = (eMultiresSubdivideModeType)( + RNA_enum_get(op->ptr, "mode")); + multiresModifier_subdivide(object, mmd, subdivide_mode); ED_object_iter_other( CTX_data_main(C), object, true, ED_object_multires_update_totlevels_cb, &mmd->totlvl); @@ -1480,6 +1503,12 @@ void OBJECT_OT_multires_subdivide(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; edit_modifier_properties(ot); + RNA_def_enum(ot->srna, + "mode", + prop_multires_subdivide_mode_type, + MULTIRES_SUBDIVIDE_CATMULL_CLARK, + "Subdivision Mode", + "How the mesh is going to be subdivided to create a new level"); } /** \} */ @@ -1697,8 +1726,12 @@ static int multires_base_apply_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + ED_sculpt_undo_push_multires_mesh_begin(C, op->type->name); + multiresModifier_base_apply(depsgraph, object, mmd); + ED_sculpt_undo_push_multires_mesh_end(C, op->type->name); + DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object); @@ -1726,6 +1759,119 @@ void OBJECT_OT_multires_base_apply(wmOperatorType *ot) ot->exec = multires_base_apply_exec; /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; + edit_modifier_properties(ot); +} + +/** \} */ + +/* ------------------------------------------------------------------- */ +/** \name Multires Unsubdivide + * \{ */ + +static int multires_unsubdivide_exec(bContext *C, wmOperator *op) +{ + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + Object *object = ED_object_active_context(C); + MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get( + op, object, eModifierType_Multires); + + if (!mmd) { + return OPERATOR_CANCELLED; + } + + int new_levels = multiresModifier_rebuild_subdiv(depsgraph, object, mmd, 1, true); + if (new_levels == 0) { + BKE_report(op->reports, RPT_ERROR, "Not valid subdivisions found to rebuild a lower level"); + return OPERATOR_CANCELLED; + } + + DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object); + + return OPERATOR_FINISHED; +} + +static int multires_unsubdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (edit_modifier_invoke_properties(C, op)) { + return multires_unsubdivide_exec(C, op); + } + else { + return OPERATOR_CANCELLED; + } +} + +void OBJECT_OT_multires_unsubdivide(wmOperatorType *ot) +{ + ot->name = "Unsubdivide"; + ot->description = "Rebuild a lower subdivision level of the current base mesh"; + ot->idname = "OBJECT_OT_multires_unsubdivide"; + + ot->poll = multires_poll; + ot->invoke = multires_unsubdivide_invoke; + ot->exec = multires_unsubdivide_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + edit_modifier_properties(ot); +} + +/** \} */ + +/* ------------------------------------------------------------------- */ +/** \name Multires Rebuild Subdivisions + * \{ */ + +static int multires_rebuild_subdiv_exec(bContext *C, wmOperator *op) +{ + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + Object *object = ED_object_active_context(C); + MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get( + op, object, eModifierType_Multires); + + if (!mmd) { + return OPERATOR_CANCELLED; + } + + int new_levels = multiresModifier_rebuild_subdiv(depsgraph, object, mmd, INT_MAX, false); + if (new_levels == 0) { + BKE_report(op->reports, RPT_ERROR, "Not valid subdivisions found to rebuild lower levels"); + return OPERATOR_CANCELLED; + } + + BKE_reportf(op->reports, RPT_INFO, "%d new levels rebuilt", new_levels); + + DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object); + + return OPERATOR_FINISHED; +} + +static int multires_rebuild_subdiv_invoke(bContext *C, + wmOperator *op, + const wmEvent *UNUSED(event)) +{ + if (edit_modifier_invoke_properties(C, op)) { + return multires_rebuild_subdiv_exec(C, op); + } + else { + return OPERATOR_CANCELLED; + } +} + +void OBJECT_OT_multires_rebuild_subdiv(wmOperatorType *ot) +{ + ot->name = "Rebuild Lower Subdivisions"; + ot->description = + "Rebuilds all possible subdivisions levels to generate a lower resolution base mesh"; + ot->idname = "OBJECT_OT_multires_rebuild_subdiv"; + + ot->poll = multires_poll; + ot->invoke = multires_rebuild_subdiv_invoke; + ot->exec = multires_rebuild_subdiv_exec; + + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; edit_modifier_properties(ot); } @@ -2066,7 +2212,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op) arm_ob = modifier_skin_armature_create(depsgraph, bmain, scene, ob); /* add a modifier to connect the new armature to the mesh */ - arm_md = (ArmatureModifierData *)modifier_new(eModifierType_Armature); + arm_md = (ArmatureModifierData *)BKE_modifier_new(eModifierType_Armature); if (arm_md) { skin_md = edit_modifier_property_get(op, ob, eModifierType_Skin); BLI_insertlinkafter(&ob->modifiers, skin_md, arm_md); @@ -2130,7 +2276,7 @@ static int correctivesmooth_bind_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (!modifier_isEnabled(scene, &csmd->modifier, eModifierMode_Realtime)) { + if (!BKE_modifier_is_enabled(scene, &csmd->modifier, eModifierMode_Realtime)) { BKE_report(op->reports, RPT_ERROR, "Modifier is disabled"); return OPERATOR_CANCELLED; } @@ -2147,8 +2293,8 @@ static int correctivesmooth_bind_exec(bContext *C, wmOperator *op) else { /* Signal to modifier to recalculate. */ CorrectiveSmoothModifierData *csmd_eval = (CorrectiveSmoothModifierData *) - modifier_get_evaluated(depsgraph, ob, &csmd->modifier); - csmd_eval->bind_coords_num = (unsigned int)-1; + BKE_modifier_get_evaluated(depsgraph, ob, &csmd->modifier); + csmd_eval->bind_coords_num = (uint)-1; /* Force modifier to run, it will call binding routine * (this has to happen outside of depsgraph evaluation). */ @@ -2226,7 +2372,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) else { /* Force modifier to run, it will call binding routine * (this has to happen outside of depsgraph evaluation). */ - MeshDeformModifierData *mmd_eval = (MeshDeformModifierData *)modifier_get_evaluated( + MeshDeformModifierData *mmd_eval = (MeshDeformModifierData *)BKE_modifier_get_evaluated( depsgraph, ob, &mmd->modifier); mmd_eval->bindfunc = ED_mesh_deform_bind_callback; object_force_modifier_bind_simple_options(depsgraph, ob, &mmd->modifier); @@ -2431,7 +2577,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) } och = BKE_ocean_init_cache(omd->cachepath, - modifier_path_relbase(bmain, ob), + BKE_modifier_path_relbase(bmain, ob), omd->bakestart, omd->bakeend, omd->wave_scale, @@ -2450,7 +2596,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) * No drivers or other modifier parameters. */ /* TODO(sergey): This operates on an original data, so no flush is needed. However, baking * usually should happen on an evaluated objects, so this seems to be deeper issue here. */ - BKE_animsys_evaluate_animdata(scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM, false); + BKE_animsys_evaluate_animdata((ID *)ob, ob->adt, f, ADT_RECALC_ANIM, false); och->time[i] = omd->time; i++; @@ -2554,8 +2700,8 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op) lmd->flag |= MOD_LAPLACIANDEFORM_BIND; } - LaplacianDeformModifierData *lmd_eval = (LaplacianDeformModifierData *)modifier_get_evaluated( - depsgraph, ob, &lmd->modifier); + LaplacianDeformModifierData *lmd_eval = (LaplacianDeformModifierData *) + BKE_modifier_get_evaluated(depsgraph, ob, &lmd->modifier); lmd_eval->flag = lmd->flag; /* Force modifier to run, it will call binding routine @@ -2633,7 +2779,7 @@ static int surfacedeform_bind_exec(bContext *C, wmOperator *op) smd->flags |= MOD_SDEF_BIND; } - SurfaceDeformModifierData *smd_eval = (SurfaceDeformModifierData *)modifier_get_evaluated( + SurfaceDeformModifierData *smd_eval = (SurfaceDeformModifierData *)BKE_modifier_get_evaluated( depsgraph, ob, &smd->modifier); smd_eval->flags = smd->flags; |