Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/object/object_edit.c
| Show First 20 Lines • Show All 1,393 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static const EnumPropertyItem *object_mode_set_itemsf( | static const EnumPropertyItem *object_mode_set_itemsf( | ||||
| bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) | bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) | ||||
| { | { | ||||
| const EnumPropertyItem *input = rna_enum_object_mode_items; | const EnumPropertyItem *input = rna_enum_object_mode_items; | ||||
| EnumPropertyItem *item = NULL; | EnumPropertyItem *item = NULL; | ||||
| Object *ob; | Object *ob; | ||||
| bGPdata *gpd; | |||||
| int totitem = 0; | int totitem = 0; | ||||
| if (!C) /* needed for docs */ | if (!C) /* needed for docs */ | ||||
| return rna_enum_object_mode_items; | return rna_enum_object_mode_items; | ||||
| ob = CTX_data_active_object(C); | ob = CTX_data_active_object(C); | ||||
| if (ob) { | if (ob) { | ||||
| const bool use_mode_particle_edit = (BLI_listbase_is_empty(&ob->particlesystem) == false) || | const bool use_mode_particle_edit = (BLI_listbase_is_empty(&ob->particlesystem) == false) || | ||||
| (ob->soft != NULL) || | (ob->soft != NULL) || | ||||
| (modifiers_findByType(ob, eModifierType_Cloth) != NULL); | (modifiers_findByType(ob, eModifierType_Cloth) != NULL); | ||||
| while (input->identifier) { | while (input->identifier) { | ||||
| if ((input->value == OB_MODE_EDIT && OB_TYPE_SUPPORT_EDITMODE(ob->type)) || | if ((input->value == OB_MODE_EDIT && OB_TYPE_SUPPORT_EDITMODE(ob->type)) || | ||||
| (input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) || | (input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) || | ||||
| (input->value == OB_MODE_PARTICLE_EDIT && use_mode_particle_edit) || | (input->value == OB_MODE_PARTICLE_EDIT && use_mode_particle_edit) || | ||||
| (ELEM(input->value, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, | (ELEM(input->value, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, | ||||
| OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) || | OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) || | ||||
| (ELEM(input->value, OB_MODE_GPENCIL_EDIT, OB_MODE_GPENCIL_PAINT, | |||||
| OB_MODE_GPENCIL_SCULPT, OB_MODE_GPENCIL_WEIGHT) && (ob->type == OB_GPENCIL)) || | |||||
| (input->value == OB_MODE_OBJECT)) | (input->value == OB_MODE_OBJECT)) | ||||
| { | { | ||||
| RNA_enum_item_add(&item, &totitem, input); | RNA_enum_item_add(&item, &totitem, input); | ||||
| } | } | ||||
| input++; | input++; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* We need at least this one! */ | /* We need at least this one! */ | ||||
| RNA_enum_items_add_value(&item, &totitem, input, OB_MODE_OBJECT); | RNA_enum_items_add_value(&item, &totitem, input, OB_MODE_OBJECT); | ||||
| } | } | ||||
| /* On top of all the rest, GPencil Stroke Edit Mode | |||||
| * is available if there's a valid gp datablock... | |||||
| */ | |||||
| gpd = CTX_data_gpencil_data(C); | |||||
| if (gpd) { | |||||
| RNA_enum_items_add_value(&item, &totitem, rna_enum_object_mode_items, OB_MODE_GPENCIL); | |||||
| } | |||||
| RNA_enum_item_end(&item, &totitem); | RNA_enum_item_end(&item, &totitem); | ||||
| *r_free = true; | *r_free = true; | ||||
| return item; | return item; | ||||
| } | } | ||||
| static const char *object_mode_op_string(int mode) | static const char *object_mode_op_string(int mode) | ||||
| { | { | ||||
| if (mode & OB_MODE_EDIT) | if (mode & OB_MODE_EDIT) | ||||
| return "OBJECT_OT_editmode_toggle"; | return "OBJECT_OT_editmode_toggle"; | ||||
| if (mode == OB_MODE_SCULPT) | if (mode == OB_MODE_SCULPT) | ||||
| return "SCULPT_OT_sculptmode_toggle"; | return "SCULPT_OT_sculptmode_toggle"; | ||||
| if (mode == OB_MODE_VERTEX_PAINT) | if (mode == OB_MODE_VERTEX_PAINT) | ||||
| return "PAINT_OT_vertex_paint_toggle"; | return "PAINT_OT_vertex_paint_toggle"; | ||||
| if (mode == OB_MODE_WEIGHT_PAINT) | if (mode == OB_MODE_WEIGHT_PAINT) | ||||
| return "PAINT_OT_weight_paint_toggle"; | return "PAINT_OT_weight_paint_toggle"; | ||||
| if (mode == OB_MODE_TEXTURE_PAINT) | if (mode == OB_MODE_TEXTURE_PAINT) | ||||
| return "PAINT_OT_texture_paint_toggle"; | return "PAINT_OT_texture_paint_toggle"; | ||||
| if (mode == OB_MODE_PARTICLE_EDIT) | if (mode == OB_MODE_PARTICLE_EDIT) | ||||
| return "PARTICLE_OT_particle_edit_toggle"; | return "PARTICLE_OT_particle_edit_toggle"; | ||||
| if (mode == OB_MODE_POSE) | if (mode == OB_MODE_POSE) | ||||
| return "OBJECT_OT_posemode_toggle"; | return "OBJECT_OT_posemode_toggle"; | ||||
| if (mode == OB_MODE_GPENCIL) | if (mode == OB_MODE_GPENCIL_EDIT) | ||||
| return "GPENCIL_OT_editmode_toggle"; | return "GPENCIL_OT_editmode_toggle"; | ||||
| if (mode == OB_MODE_GPENCIL_PAINT) | |||||
| return "GPENCIL_OT_paintmode_toggle"; | |||||
| if (mode == OB_MODE_GPENCIL_SCULPT) | |||||
| return "GPENCIL_OT_sculptmode_toggle"; | |||||
| if (mode == OB_MODE_GPENCIL_WEIGHT) | |||||
| return "GPENCIL_OT_weightmode_toggle"; | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /* checks the mode to be set is compatible with the object | /* checks the mode to be set is compatible with the object | ||||
| * should be made into a generic function | * should be made into a generic function | ||||
| */ | */ | ||||
| static bool object_mode_compat_test(Object *ob, eObjectMode mode) | static bool object_mode_compat_test(Object *ob, eObjectMode mode) | ||||
| { | { | ||||
| if (ob) { | if (ob) { | ||||
| if (mode == OB_MODE_OBJECT) | if (mode == OB_MODE_OBJECT) | ||||
| return true; | return true; | ||||
| else if (mode == OB_MODE_GPENCIL) | |||||
| return true; /* XXX: assume this is the case for now... */ | |||||
| switch (ob->type) { | switch (ob->type) { | ||||
| case OB_MESH: | case OB_MESH: | ||||
| if (mode & (OB_MODE_EDIT | OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | | if (mode & (OB_MODE_EDIT | OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | | ||||
| OB_MODE_TEXTURE_PAINT | OB_MODE_PARTICLE_EDIT)) | OB_MODE_TEXTURE_PAINT | OB_MODE_PARTICLE_EDIT)) | ||||
| { | { | ||||
| return true; | return true; | ||||
| } | } | ||||
| break; | break; | ||||
| case OB_CURVE: | case OB_CURVE: | ||||
| case OB_SURF: | case OB_SURF: | ||||
| case OB_FONT: | case OB_FONT: | ||||
| case OB_MBALL: | case OB_MBALL: | ||||
| if (mode & (OB_MODE_EDIT)) | if (mode & (OB_MODE_EDIT)) | ||||
| return true; | return true; | ||||
| break; | break; | ||||
| case OB_LATTICE: | case OB_LATTICE: | ||||
| if (mode & (OB_MODE_EDIT | OB_MODE_WEIGHT_PAINT)) | if (mode & (OB_MODE_EDIT | OB_MODE_WEIGHT_PAINT)) | ||||
| return true; | return true; | ||||
| break; | break; | ||||
| case OB_ARMATURE: | case OB_ARMATURE: | ||||
| if (mode & (OB_MODE_EDIT | OB_MODE_POSE)) | if (mode & (OB_MODE_EDIT | OB_MODE_POSE)) | ||||
| return true; | return true; | ||||
| break; | break; | ||||
| case OB_GPENCIL: | |||||
| if (mode & (OB_MODE_GPENCIL_EDIT | OB_MODE_GPENCIL_PAINT | | |||||
| OB_MODE_GPENCIL_SCULPT | OB_MODE_GPENCIL_WEIGHT)) | |||||
| { | |||||
| return true; | |||||
| } | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| /** | /** | ||||
| * Sets the mode to a compatible state (use before entering the mode). | * Sets the mode to a compatible state (use before entering the mode). | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
| static int object_mode_set_exec(bContext *C, wmOperator *op) | static int object_mode_set_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Object *ob = CTX_data_active_object(C); | Object *ob = CTX_data_active_object(C); | ||||
| bGPdata *gpd = CTX_data_gpencil_data(C); | bGPdata *gpd = CTX_data_gpencil_data(C); | ||||
| eObjectMode mode = RNA_enum_get(op->ptr, "mode"); | eObjectMode mode = RNA_enum_get(op->ptr, "mode"); | ||||
| eObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT; | eObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT; | ||||
| const bool toggle = RNA_boolean_get(op->ptr, "toggle"); | const bool toggle = RNA_boolean_get(op->ptr, "toggle"); | ||||
| if (gpd) { | /* if type is OB_GPENCIL, select mode for grease pencil strokes */ | ||||
| /* GP Mode is not bound to a specific object. Therefore, | if ((ob) && (ob->type == OB_GPENCIL)) { | ||||
| * we don't want it to be actually saved on any objects, | if ((ob->gpd) && (ob->gpd == gpd)) { | ||||
| * as weirdness can happen if you select other objects, | if (ELEM(mode, OB_MODE_OBJECT, OB_MODE_EDIT, OB_MODE_POSE)) { | ||||
| * or load old files. | ob->restore_mode = OB_MODE_OBJECT; | ||||
| * | if (ELEM(ob->mode, OB_MODE_OBJECT, OB_MODE_EDIT, OB_MODE_GPENCIL_EDIT)) { | ||||
| * Instead, we use the following 2 rules to ensure that | WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); | ||||
| * the mode selector works as expected: | } | ||||
| * 1) If there's no object, we want to enter editmode. | if (ob->mode == OB_MODE_GPENCIL_PAINT) { | ||||
| * (i.e. with no object, we're in object mode) | WM_operator_name_call(C, "GPENCIL_OT_paintmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); | ||||
| * 2) Otherwise, exit stroke editmode, so that we can | } | ||||
| * enter another mode... | if (ob->mode == OB_MODE_GPENCIL_SCULPT) { | ||||
| */ | WM_operator_name_call(C, "GPENCIL_OT_sculptmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); | ||||
| if (!ob || (gpd->flag & GP_DATA_STROKE_EDITMODE)) { | } | ||||
| if (ob->mode == OB_MODE_GPENCIL_WEIGHT) { | |||||
| WM_operator_name_call(C, "GPENCIL_OT_weightmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); | |||||
| } | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| if (mode == OB_MODE_GPENCIL_EDIT) { | |||||
| ob->restore_mode = ob->mode; | |||||
| WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); | WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); | ||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| if (mode == OB_MODE_GPENCIL_PAINT) { | |||||
| ob->restore_mode = ob->mode; | |||||
| WM_operator_name_call(C, "GPENCIL_OT_paintmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| if (mode == OB_MODE_GPENCIL_SCULPT) { | |||||
| ob->restore_mode = ob->mode; | |||||
| WM_operator_name_call(C, "GPENCIL_OT_sculptmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| if (mode == OB_MODE_GPENCIL_WEIGHT) { | |||||
| ob->restore_mode = ob->mode; | |||||
| WM_operator_name_call(C, "GPENCIL_OT_weightmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| if (!ob || !object_mode_compat_test(ob, mode)) | if (!ob || !object_mode_compat_test(ob, mode)) | ||||
| return OPERATOR_PASS_THROUGH; | return OPERATOR_PASS_THROUGH; | ||||
| if (ob->mode != mode) { | if (ob->mode != mode) { | ||||
| /* we should be able to remove this call, each operator calls */ | /* we should be able to remove this call, each operator calls */ | ||||
| ▲ Show 20 Lines • Show All 523 Lines • Show Last 20 Lines | |||||