36a08d15913fdcf07b348a7828fdf78f825ee5c3
[blender.git] / source / blender / editors / object / object_edit.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup edobj
22  */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <math.h>
27 #include <time.h>
28 #include <float.h>
29 #include <ctype.h>
30 #include <stddef.h>  //for offsetof
31
32 #include "MEM_guardedalloc.h"
33
34 #include "BLI_blenlib.h"
35 #include "BLI_utildefines.h"
36 #include "BLI_ghash.h"
37
38 #include "BLT_translation.h"
39
40 #include "DNA_armature_types.h"
41 #include "DNA_collection_types.h"
42 #include "DNA_curve_types.h"
43 #include "DNA_gpencil_types.h"
44 #include "DNA_material_types.h"
45 #include "DNA_meta_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_object_types.h"
48 #include "DNA_object_force_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_vfont_types.h"
51 #include "DNA_mesh_types.h"
52 #include "DNA_lattice_types.h"
53 #include "DNA_workspace_types.h"
54
55 #include "IMB_imbuf_types.h"
56
57 #include "BKE_anim.h"
58 #include "BKE_collection.h"
59 #include "BKE_constraint.h"
60 #include "BKE_context.h"
61 #include "BKE_curve.h"
62 #include "BKE_editlattice.h"
63 #include "BKE_effect.h"
64 #include "BKE_global.h"
65 #include "BKE_image.h"
66 #include "BKE_lattice.h"
67 #include "BKE_layer.h"
68 #include "BKE_main.h"
69 #include "BKE_material.h"
70 #include "BKE_mball.h"
71 #include "BKE_mesh.h"
72 #include "BKE_modifier.h"
73 #include "BKE_object.h"
74 #include "BKE_paint.h"
75 #include "BKE_particle.h"
76 #include "BKE_pointcache.h"
77 #include "BKE_softbody.h"
78 #include "BKE_editmesh.h"
79 #include "BKE_report.h"
80 #include "BKE_scene.h"
81 #include "BKE_workspace.h"
82
83 #include "DEG_depsgraph.h"
84 #include "DEG_depsgraph_build.h"
85
86 #include "ED_anim_api.h"
87 #include "ED_armature.h"
88 #include "ED_curve.h"
89 #include "ED_mesh.h"
90 #include "ED_mball.h"
91 #include "ED_lattice.h"
92 #include "ED_object.h"
93 #include "ED_outliner.h"
94 #include "ED_screen.h"
95 #include "ED_undo.h"
96 #include "ED_image.h"
97 #include "ED_gpencil.h"
98
99 #include "RNA_access.h"
100 #include "RNA_define.h"
101 #include "RNA_enum_types.h"
102
103 /* for menu/popup icons etc etc*/
104
105 #include "UI_interface.h"
106 #include "UI_resources.h"
107
108 #include "WM_api.h"
109 #include "WM_types.h"
110 #include "WM_message.h"
111 #include "WM_toolsystem.h"
112
113 #include "object_intern.h"  // own include
114
115 /* prototypes */
116 typedef struct MoveToCollectionData MoveToCollectionData;
117 static void move_to_collection_menus_items(struct uiLayout *layout,
118                                            struct MoveToCollectionData *menu);
119
120 /* ************* XXX **************** */
121 static void error(const char *UNUSED(arg))
122 {
123 }
124
125 /* port over here */
126 static void error_libdata(void)
127 {
128 }
129
130 Object *ED_object_context(bContext *C)
131 {
132   return CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
133 }
134
135 /* find the correct active object per context
136  * note: context can be NULL when called from a enum with PROP_ENUM_NO_CONTEXT */
137 Object *ED_object_active_context(bContext *C)
138 {
139   Object *ob = NULL;
140   if (C) {
141     ob = ED_object_context(C);
142     if (!ob) {
143       ob = CTX_data_active_object(C);
144     }
145   }
146   return ob;
147 }
148
149 /* ********************** object hiding *************************** */
150
151 static bool object_hide_poll(bContext *C)
152 {
153   if (CTX_wm_space_outliner(C) != NULL) {
154     return ED_outliner_collections_editor_poll(C);
155   }
156   else {
157     return ED_operator_view3d_active(C);
158   }
159 }
160
161 static int object_hide_view_clear_exec(bContext *C, wmOperator *op)
162 {
163   Scene *scene = CTX_data_scene(C);
164   ViewLayer *view_layer = CTX_data_view_layer(C);
165   const bool select = RNA_boolean_get(op->ptr, "select");
166   bool changed = false;
167
168   for (Base *base = view_layer->object_bases.first; base; base = base->next) {
169     if (base->flag & BASE_HIDDEN) {
170       base->flag &= ~BASE_HIDDEN;
171       changed = true;
172
173       if (select) {
174         /* We cannot call `ED_object_base_select` because
175          * base is not selectable while it is hidden. */
176         base->flag |= BASE_SELECTED;
177         BKE_scene_object_base_flag_sync_from_base(base);
178       }
179     }
180   }
181
182   if (!changed) {
183     return OPERATOR_CANCELLED;
184   }
185
186   BKE_layer_collection_sync(scene, view_layer);
187   DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
188   WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
189
190   return OPERATOR_FINISHED;
191 }
192
193 void OBJECT_OT_hide_view_clear(wmOperatorType *ot)
194 {
195   /* identifiers */
196   ot->name = "Show Hidden Objects";
197   ot->description = "Reveal temporarily hidden objects";
198   ot->idname = "OBJECT_OT_hide_view_clear";
199
200   /* api callbacks */
201   ot->exec = object_hide_view_clear_exec;
202   ot->poll = object_hide_poll;
203
204   /* flags */
205   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
206
207   PropertyRNA *prop = RNA_def_boolean(ot->srna, "select", true, "Select", "");
208   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
209 }
210
211 static int object_hide_view_set_exec(bContext *C, wmOperator *op)
212 {
213   Scene *scene = CTX_data_scene(C);
214   ViewLayer *view_layer = CTX_data_view_layer(C);
215   const bool unselected = RNA_boolean_get(op->ptr, "unselected");
216   bool changed = false;
217
218   /* Hide selected or unselected objects. */
219   for (Base *base = view_layer->object_bases.first; base; base = base->next) {
220     if (!(base->flag & BASE_VISIBLE)) {
221       continue;
222     }
223
224     if (!unselected) {
225       if (base->flag & BASE_SELECTED) {
226         ED_object_base_select(base, BA_DESELECT);
227         base->flag |= BASE_HIDDEN;
228         changed = true;
229       }
230     }
231     else {
232       if (!(base->flag & BASE_SELECTED)) {
233         ED_object_base_select(base, BA_DESELECT);
234         base->flag |= BASE_HIDDEN;
235         changed = true;
236       }
237     }
238   }
239   if (!changed) {
240     return OPERATOR_CANCELLED;
241   }
242
243   BKE_layer_collection_sync(scene, view_layer);
244   DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
245   WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
246
247   return OPERATOR_FINISHED;
248 }
249
250 void OBJECT_OT_hide_view_set(wmOperatorType *ot)
251 {
252   /* identifiers */
253   ot->name = "Hide Objects";
254   ot->description = "Temporarily hide objects from the viewport";
255   ot->idname = "OBJECT_OT_hide_view_set";
256
257   /* api callbacks */
258   ot->exec = object_hide_view_set_exec;
259   ot->poll = object_hide_poll;
260
261   /* flags */
262   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
263
264   PropertyRNA *prop;
265   prop = RNA_def_boolean(
266       ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
267   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
268 }
269
270 static int object_hide_collection_exec(bContext *C, wmOperator *op)
271 {
272   wmWindow *win = CTX_wm_window(C);
273
274   int index = RNA_int_get(op->ptr, "collection_index");
275   const bool extend = (win->eventstate->shift != 0) || RNA_boolean_get(op->ptr, "toggle");
276
277   if (win->eventstate->alt != 0) {
278     index += 10;
279   }
280
281   Scene *scene = CTX_data_scene(C);
282   ViewLayer *view_layer = CTX_data_view_layer(C);
283   LayerCollection *lc = BKE_layer_collection_from_index(view_layer, index);
284
285   if (!lc) {
286     return OPERATOR_CANCELLED;
287   }
288
289   DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
290
291   BKE_layer_collection_isolate(scene, view_layer, lc, extend);
292
293   WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
294
295   return OPERATOR_FINISHED;
296 }
297
298 #define COLLECTION_INVALID_INDEX -1
299
300 void ED_collection_hide_menu_draw(const bContext *C, uiLayout *layout)
301 {
302   ViewLayer *view_layer = CTX_data_view_layer(C);
303   LayerCollection *lc_scene = view_layer->layer_collections.first;
304
305   uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
306
307   for (LayerCollection *lc = lc_scene->layer_collections.first; lc; lc = lc->next) {
308     int index = BKE_layer_collection_findindex(view_layer, lc);
309     uiLayout *row = uiLayoutRow(layout, false);
310
311     if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
312       continue;
313     }
314
315     if (lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) {
316       continue;
317     }
318
319     int icon = ICON_NONE;
320     if (BKE_layer_collection_has_selected_objects(view_layer, lc)) {
321       icon = ICON_LAYER_ACTIVE;
322     }
323     else if (lc->runtime_flag & LAYER_COLLECTION_HAS_OBJECTS) {
324       icon = ICON_LAYER_USED;
325     }
326
327     uiItemIntO(row,
328                lc->collection->id.name + 2,
329                icon,
330                "OBJECT_OT_hide_collection",
331                "collection_index",
332                index);
333   }
334 }
335
336 static int object_hide_collection_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
337 {
338   /* Immediately execute if collection index was specified. */
339   int index = RNA_int_get(op->ptr, "collection_index");
340   if (index != COLLECTION_INVALID_INDEX) {
341     return object_hide_collection_exec(C, op);
342   }
343
344   /* Open popup menu. */
345   const char *title = CTX_IFACE_(op->type->translation_context, op->type->name);
346   uiPopupMenu *pup = UI_popup_menu_begin(C, title, ICON_GROUP);
347   uiLayout *layout = UI_popup_menu_layout(pup);
348
349   ED_collection_hide_menu_draw(C, layout);
350
351   UI_popup_menu_end(C, pup);
352
353   return OPERATOR_INTERFACE;
354 }
355
356 void OBJECT_OT_hide_collection(wmOperatorType *ot)
357 {
358   /* identifiers */
359   ot->name = "Hide Collection";
360   ot->description = "Show only objects in collection (Shift to extend)";
361   ot->idname = "OBJECT_OT_hide_collection";
362
363   /* api callbacks */
364   ot->exec = object_hide_collection_exec;
365   ot->invoke = object_hide_collection_invoke;
366   ot->poll = ED_operator_view3d_active;
367
368   /* flags */
369   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
370
371   /* Properties. */
372   PropertyRNA *prop;
373   prop = RNA_def_int(ot->srna,
374                      "collection_index",
375                      COLLECTION_INVALID_INDEX,
376                      COLLECTION_INVALID_INDEX,
377                      INT_MAX,
378                      "Collection Index",
379                      "Index of the collection to change visibility",
380                      0,
381                      INT_MAX);
382   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
383   prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "Toggle visibility");
384   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
385 }
386
387 /* ******************* toggle editmode operator  ***************** */
388
389 static bool mesh_needs_keyindex(Main *bmain, const Mesh *me)
390 {
391   if (me->key) {
392     return false; /* will be added */
393   }
394
395   for (const Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
396     if ((ob->parent) && (ob->parent->data == me) && ELEM(ob->partype, PARVERT1, PARVERT3)) {
397       return true;
398     }
399     if (ob->data == me) {
400       for (const ModifierData *md = ob->modifiers.first; md; md = md->next) {
401         if (md->type == eModifierType_Hook) {
402           return true;
403         }
404       }
405     }
406   }
407   return false;
408 }
409
410 /**
411  * Load EditMode data back into the object,
412  * optionally freeing the editmode data.
413  */
414 static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool freedata)
415 {
416   if (obedit == NULL) {
417     return false;
418   }
419
420   if (obedit->type == OB_MESH) {
421     Mesh *me = obedit->data;
422     if (me->edit_mesh == NULL) {
423       return false;
424     }
425
426     if (me->edit_mesh->bm->totvert > MESH_MAX_VERTS) {
427       error("Too many vertices");
428       return false;
429     }
430
431     EDBM_mesh_load(bmain, obedit);
432
433     if (freedata) {
434       EDBM_mesh_free(me->edit_mesh);
435       MEM_freeN(me->edit_mesh);
436       me->edit_mesh = NULL;
437     }
438     /* will be recalculated as needed. */
439     {
440       ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
441       ED_mesh_mirror_topo_table(NULL, NULL, 'e');
442     }
443   }
444   else if (obedit->type == OB_ARMATURE) {
445     const bArmature *arm = obedit->data;
446     if (arm->edbo == NULL) {
447       return false;
448     }
449     ED_armature_from_edit(bmain, obedit->data);
450     if (freedata) {
451       ED_armature_edit_free(obedit->data);
452     }
453     /* TODO(sergey): Pose channels might have been changed, so need
454      * to inform dependency graph about this. But is it really the
455      * best place to do this?
456      */
457     DEG_relations_tag_update(bmain);
458   }
459   else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
460     const Curve *cu = obedit->data;
461     if (cu->editnurb == NULL) {
462       return false;
463     }
464     ED_curve_editnurb_load(bmain, obedit);
465     if (freedata) {
466       ED_curve_editnurb_free(obedit);
467     }
468   }
469   else if (obedit->type == OB_FONT) {
470     const Curve *cu = obedit->data;
471     if (cu->editfont == NULL) {
472       return false;
473     }
474     ED_curve_editfont_load(obedit);
475     if (freedata) {
476       ED_curve_editfont_free(obedit);
477     }
478   }
479   else if (obedit->type == OB_LATTICE) {
480     const Lattice *lt = obedit->data;
481     if (lt->editlatt == NULL) {
482       return false;
483     }
484     BKE_editlattice_load(obedit);
485     if (freedata) {
486       BKE_editlattice_free(obedit);
487     }
488   }
489   else if (obedit->type == OB_MBALL) {
490     const MetaBall *mb = obedit->data;
491     if (mb->editelems == NULL) {
492       return false;
493     }
494     ED_mball_editmball_load(obedit);
495     if (freedata) {
496       ED_mball_editmball_free(obedit);
497     }
498   }
499
500   return true;
501 }
502
503 bool ED_object_editmode_load(Main *bmain, Object *obedit)
504 {
505   return ED_object_editmode_load_ex(bmain, obedit, false);
506 }
507
508 /**
509  * \param flag:
510  * - If #EM_FREEDATA isn't in the flag, use ED_object_editmode_load directly.
511  */
512 bool ED_object_editmode_exit_ex(Main *bmain, Scene *scene, Object *obedit, int flag)
513 {
514   const bool freedata = (flag & EM_FREEDATA) != 0;
515
516   if (ED_object_editmode_load_ex(bmain, obedit, freedata) == false) {
517     /* in rare cases (background mode) its possible active object
518      * is flagged for editmode, without 'obedit' being set [#35489] */
519     if (UNLIKELY(obedit && obedit->mode & OB_MODE_EDIT)) {
520       obedit->mode &= ~OB_MODE_EDIT;
521     }
522     return true;
523   }
524
525   /* freedata only 0 now on file saves and render */
526   if (freedata) {
527     ListBase pidlist;
528     PTCacheID *pid;
529
530     /* flag object caches as outdated */
531     BKE_ptcache_ids_from_object(&pidlist, obedit, scene, 0);
532     for (pid = pidlist.first; pid; pid = pid->next) {
533       /* particles don't need reset on geometry change */
534       if (pid->type != PTCACHE_TYPE_PARTICLES) {
535         pid->cache->flag |= PTCACHE_OUTDATED;
536       }
537     }
538     BLI_freelistN(&pidlist);
539
540     BKE_particlesystem_reset_all(obedit);
541     BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED);
542
543     /* also flush ob recalc, doesn't take much overhead, but used for particles */
544     DEG_id_tag_update(&obedit->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
545
546     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
547
548     obedit->mode &= ~OB_MODE_EDIT;
549   }
550
551   return (obedit->mode & OB_MODE_EDIT) == 0;
552 }
553
554 bool ED_object_editmode_exit(bContext *C, int flag)
555 {
556   Main *bmain = CTX_data_main(C);
557   Scene *scene = CTX_data_scene(C);
558   Object *obedit = CTX_data_edit_object(C);
559   return ED_object_editmode_exit_ex(bmain, scene, obedit, flag);
560 }
561
562 bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag)
563 {
564   bool ok = false;
565
566   if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob)) {
567     return false;
568   }
569
570   /* this checks actual object->data, for cases when other scenes have it in editmode context */
571   if (BKE_object_is_in_editmode(ob)) {
572     return true;
573   }
574
575   if (BKE_object_obdata_is_libdata(ob)) {
576     error_libdata();
577     return false;
578   }
579
580   ob->restore_mode = ob->mode;
581
582   ob->mode = OB_MODE_EDIT;
583
584   if (ob->type == OB_MESH) {
585     BMEditMesh *em;
586     ok = 1;
587
588     const bool use_key_index = mesh_needs_keyindex(bmain, ob->data);
589
590     EDBM_mesh_make(ob, scene->toolsettings->selectmode, use_key_index);
591
592     em = BKE_editmesh_from_object(ob);
593     if (LIKELY(em)) {
594       /* order doesn't matter */
595       EDBM_mesh_normals_update(em);
596       BKE_editmesh_tessface_calc(em);
597     }
598
599     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_MESH, NULL);
600   }
601   else if (ob->type == OB_ARMATURE) {
602     ok = 1;
603     ED_armature_to_edit(ob->data);
604     /* to ensure all goes in restposition and without striding */
605
606     /* XXX: should this be ID_RECALC_GEOMETRY? */
607     DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
608
609     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_ARMATURE, scene);
610   }
611   else if (ob->type == OB_FONT) {
612     ok = 1;
613     ED_curve_editfont_make(ob);
614
615     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_TEXT, scene);
616   }
617   else if (ob->type == OB_MBALL) {
618     ok = 1;
619     ED_mball_editmball_make(ob);
620
621     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_MBALL, scene);
622   }
623   else if (ob->type == OB_LATTICE) {
624     ok = 1;
625     BKE_editlattice_make(ob);
626
627     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_LATTICE, scene);
628   }
629   else if (ob->type == OB_SURF || ob->type == OB_CURVE) {
630     ok = 1;
631     ED_curve_editnurb_make(ob);
632
633     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_CURVE, scene);
634   }
635
636   if (ok) {
637     DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
638   }
639   else {
640     if ((flag & EM_NO_CONTEXT) == 0) {
641       ob->mode &= ~OB_MODE_EDIT;
642     }
643     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
644   }
645
646   return (ob->mode & OB_MODE_EDIT) != 0;
647 }
648
649 bool ED_object_editmode_enter(bContext *C, int flag)
650 {
651   Main *bmain = CTX_data_main(C);
652   Scene *scene = CTX_data_scene(C);
653   Object *ob;
654
655   /* Active layer checked here for view3d,
656    * callers that don't want view context can call the extended version. */
657   ob = CTX_data_active_object(C);
658   if ((ob == NULL) || ID_IS_LINKED(ob)) {
659     return false;
660   }
661   return ED_object_editmode_enter_ex(bmain, scene, ob, flag);
662 }
663
664 static int editmode_toggle_exec(bContext *C, wmOperator *op)
665 {
666   struct wmMsgBus *mbus = CTX_wm_message_bus(C);
667   const int mode_flag = OB_MODE_EDIT;
668   const bool is_mode_set = (CTX_data_edit_object(C) != NULL);
669   Main *bmain = CTX_data_main(C);
670   Scene *scene = CTX_data_scene(C);
671   ViewLayer *view_layer = CTX_data_view_layer(C);
672   View3D *v3d = CTX_wm_view3d(C);
673   Object *obact = OBACT(view_layer);
674
675   if (!is_mode_set) {
676     if (!ED_object_mode_compat_set(C, obact, mode_flag, op->reports)) {
677       return OPERATOR_CANCELLED;
678     }
679   }
680
681   if (!is_mode_set) {
682     ED_object_editmode_enter(C, 0);
683     if (obact->mode & mode_flag) {
684       FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob) {
685         if ((ob != obact) && (ob->type == obact->type)) {
686           ED_object_editmode_enter_ex(bmain, scene, ob, EM_NO_CONTEXT);
687         }
688       }
689       FOREACH_SELECTED_OBJECT_END;
690     }
691   }
692   else {
693     ED_object_editmode_exit(C, EM_FREEDATA);
694     if ((obact->mode & mode_flag) == 0) {
695       FOREACH_OBJECT_BEGIN (view_layer, ob) {
696         if ((ob != obact) && (ob->type == obact->type)) {
697           ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
698         }
699       }
700       FOREACH_OBJECT_END;
701     }
702   }
703
704   WM_msg_publish_rna_prop(mbus, &obact->id, obact, Object, mode);
705
706   if (G.background == false) {
707     WM_toolsystem_update_from_context_view3d(C);
708   }
709
710   return OPERATOR_FINISHED;
711 }
712
713 static bool editmode_toggle_poll(bContext *C)
714 {
715   Object *ob = CTX_data_active_object(C);
716
717   /* covers proxies too */
718   if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob->data)) {
719     return 0;
720   }
721
722   /* if hidden but in edit mode, we still display */
723   if ((ob->restrictflag & OB_RESTRICT_VIEWPORT) && !(ob->mode & OB_MODE_EDIT)) {
724     return 0;
725   }
726
727   return OB_TYPE_SUPPORT_EDITMODE(ob->type);
728 }
729
730 void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
731 {
732
733   /* identifiers */
734   ot->name = "Toggle Editmode";
735   ot->description = "Toggle object's editmode";
736   ot->idname = "OBJECT_OT_editmode_toggle";
737
738   /* api callbacks */
739   ot->exec = editmode_toggle_exec;
740   ot->poll = editmode_toggle_poll;
741
742   /* flags */
743   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
744 }
745
746 /* *************************** */
747
748 static int posemode_exec(bContext *C, wmOperator *op)
749 {
750   struct wmMsgBus *mbus = CTX_wm_message_bus(C);
751   Base *base = CTX_data_active_base(C);
752
753   /* If the base is NULL it means we have an active object, but the object itself is hidden. */
754   if (base == NULL) {
755     return OPERATOR_CANCELLED;
756   }
757
758   Object *obact = base->object;
759   const int mode_flag = OB_MODE_POSE;
760   bool is_mode_set = (obact->mode & mode_flag) != 0;
761
762   if (!is_mode_set) {
763     if (!ED_object_mode_compat_set(C, obact, mode_flag, op->reports)) {
764       return OPERATOR_CANCELLED;
765     }
766   }
767
768   if (obact->type != OB_ARMATURE) {
769     return OPERATOR_PASS_THROUGH;
770   }
771
772   if (obact == CTX_data_edit_object(C)) {
773     ED_object_editmode_exit(C, EM_FREEDATA);
774     is_mode_set = false;
775   }
776
777   if (is_mode_set) {
778     bool ok = ED_object_posemode_exit(C, obact);
779     if (ok) {
780       struct Main *bmain = CTX_data_main(C);
781       ViewLayer *view_layer = CTX_data_view_layer(C);
782       FOREACH_OBJECT_BEGIN (view_layer, ob) {
783         if ((ob != obact) && (ob->type == OB_ARMATURE) && (ob->mode & mode_flag)) {
784           ED_object_posemode_exit_ex(bmain, ob);
785         }
786       }
787       FOREACH_OBJECT_END;
788     }
789   }
790   else {
791     bool ok = ED_object_posemode_enter(C, obact);
792     if (ok) {
793       struct Main *bmain = CTX_data_main(C);
794       ViewLayer *view_layer = CTX_data_view_layer(C);
795       View3D *v3d = CTX_wm_view3d(C);
796       FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob) {
797         if ((ob != obact) && (ob->type == OB_ARMATURE) && (ob->mode == OB_MODE_OBJECT) &&
798             (!ID_IS_LINKED(ob))) {
799           ED_object_posemode_enter_ex(bmain, ob);
800         }
801       }
802       FOREACH_SELECTED_OBJECT_END;
803     }
804   }
805
806   WM_msg_publish_rna_prop(mbus, &obact->id, obact, Object, mode);
807
808   if (G.background == false) {
809     WM_toolsystem_update_from_context_view3d(C);
810   }
811
812   return OPERATOR_FINISHED;
813 }
814
815 void OBJECT_OT_posemode_toggle(wmOperatorType *ot)
816 {
817   /* identifiers */
818   ot->name = "Toggle Pose Mode";
819   ot->idname = "OBJECT_OT_posemode_toggle";
820   ot->description = "Enable or disable posing/selecting bones";
821
822   /* api callbacks */
823   ot->exec = posemode_exec;
824   ot->poll = ED_operator_object_active_editable;
825
826   /* flag */
827   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
828 }
829
830 /* ******************* force field toggle operator ***************** */
831
832 void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object)
833 {
834   PartDeflect *pd = object->pd;
835   ModifierData *md = modifiers_findByType(object, eModifierType_Surface);
836
837   /* add/remove modifier as needed */
838   if (!md) {
839     if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) &&
840         !ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) {
841       if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) {
842         ED_object_modifier_add(NULL, bmain, scene, object, NULL, eModifierType_Surface);
843       }
844     }
845   }
846   else {
847     if (!pd || (pd->shape != PFIELD_SHAPE_SURFACE) ||
848         ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) {
849       ED_object_modifier_remove(NULL, bmain, object, md);
850     }
851   }
852 }
853
854 static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op))
855 {
856   Object *ob = CTX_data_active_object(C);
857
858   if (ob->pd == NULL) {
859     ob->pd = BKE_partdeflect_new(PFIELD_FORCE);
860   }
861   else if (ob->pd->forcefield == 0) {
862     ob->pd->forcefield = PFIELD_FORCE;
863   }
864   else {
865     ob->pd->forcefield = 0;
866   }
867
868   ED_object_check_force_modifiers(CTX_data_main(C), CTX_data_scene(C), ob);
869   WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
870   WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
871
872   DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
873
874   return OPERATOR_FINISHED;
875 }
876
877 void OBJECT_OT_forcefield_toggle(wmOperatorType *ot)
878 {
879
880   /* identifiers */
881   ot->name = "Toggle Force Field";
882   ot->description = "Toggle object's force field";
883   ot->idname = "OBJECT_OT_forcefield_toggle";
884
885   /* api callbacks */
886   ot->exec = forcefield_toggle_exec;
887   ot->poll = ED_operator_object_active_editable;
888
889   /* flags */
890   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
891 }
892
893 /* ********************************************** */
894 /* Motion Paths */
895
896 /* For the objects with animation: update paths for those that have got them
897  * This should selectively update paths that exist...
898  *
899  * To be called from various tools that do incremental updates
900  */
901 void ED_objects_recalculate_paths(bContext *C, Scene *scene, bool current_frame_only)
902 {
903   /* Transform doesn't always have context available to do update. */
904   if (C == NULL) {
905     return;
906   }
907
908   Main *bmain = CTX_data_main(C);
909   /* NOTE: Dependency graph will be evaluated at all the frames, but we first need to access some
910    * nested pointers, like animation data. */
911   Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
912   ListBase targets = {NULL, NULL};
913
914   /* loop over objects in scene */
915   CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
916     /* set flag to force recalc, then grab path(s) from object */
917     ob->avs.recalc |= ANIMVIZ_RECALC_PATHS;
918     animviz_get_object_motionpaths(ob, &targets);
919   }
920   CTX_DATA_END;
921
922   /* recalculate paths, then free */
923   animviz_calc_motionpaths(depsgraph, bmain, scene, &targets, true, current_frame_only);
924   BLI_freelistN(&targets);
925
926   if (!current_frame_only) {
927     /* Tag objects for copy on write - so paths will draw/redraw
928      * For currently frame only we update evaluated object directly. */
929     CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
930       if (ob->mpath) {
931         DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
932       }
933     }
934     CTX_DATA_END;
935   }
936 }
937
938 /* show popup to determine settings */
939 static int object_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
940 {
941   Object *ob = CTX_data_active_object(C);
942
943   if (ob == NULL) {
944     return OPERATOR_CANCELLED;
945   }
946
947   /* set default settings from existing/stored settings */
948   {
949     bAnimVizSettings *avs = &ob->avs;
950
951     RNA_int_set(op->ptr, "start_frame", avs->path_sf);
952     RNA_int_set(op->ptr, "end_frame", avs->path_ef);
953   }
954
955   /* show popup dialog to allow editing of range... */
956   /* FIXME: hardcoded dimensions here are just arbitrary */
957   return WM_operator_props_dialog_popup(C, op, 200, 200);
958 }
959
960 /* Calculate/recalculate whole paths (avs.path_sf to avs.path_ef) */
961 static int object_calculate_paths_exec(bContext *C, wmOperator *op)
962 {
963   Scene *scene = CTX_data_scene(C);
964   int start = RNA_int_get(op->ptr, "start_frame");
965   int end = RNA_int_get(op->ptr, "end_frame");
966
967   /* set up path data for bones being calculated */
968   CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
969     bAnimVizSettings *avs = &ob->avs;
970
971     /* grab baking settings from operator settings */
972     avs->path_sf = start;
973     avs->path_ef = end;
974
975     /* verify that the selected object has the appropriate settings */
976     animviz_verify_motionpaths(op->reports, scene, ob, NULL);
977   }
978   CTX_DATA_END;
979
980   /* calculate the paths for objects that have them (and are tagged to get refreshed) */
981   ED_objects_recalculate_paths(C, scene, false);
982
983   /* notifiers for updates */
984   WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
985
986   return OPERATOR_FINISHED;
987 }
988
989 void OBJECT_OT_paths_calculate(wmOperatorType *ot)
990 {
991   /* identifiers */
992   ot->name = "Calculate Object Paths";
993   ot->idname = "OBJECT_OT_paths_calculate";
994   ot->description = "Calculate motion paths for the selected objects";
995
996   /* api callbacks */
997   ot->invoke = object_calculate_paths_invoke;
998   ot->exec = object_calculate_paths_exec;
999   ot->poll = ED_operator_object_active_editable;
1000
1001   /* flags */
1002   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1003
1004   /* properties */
1005   RNA_def_int(ot->srna,
1006               "start_frame",
1007               1,
1008               MINAFRAME,
1009               MAXFRAME,
1010               "Start",
1011               "First frame to calculate object paths on",
1012               MINFRAME,
1013               MAXFRAME / 2.0);
1014   RNA_def_int(ot->srna,
1015               "end_frame",
1016               250,
1017               MINAFRAME,
1018               MAXFRAME,
1019               "End",
1020               "Last frame to calculate object paths on",
1021               MINFRAME,
1022               MAXFRAME / 2.0);
1023 }
1024
1025 /* --------- */
1026
1027 static bool object_update_paths_poll(bContext *C)
1028 {
1029   if (ED_operator_object_active_editable(C)) {
1030     Object *ob = ED_object_active_context(C);
1031     return (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
1032   }
1033
1034   return false;
1035 }
1036
1037 static int object_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
1038 {
1039   Scene *scene = CTX_data_scene(C);
1040
1041   if (scene == NULL) {
1042     return OPERATOR_CANCELLED;
1043   }
1044
1045   /* calculate the paths for objects that have them (and are tagged to get refreshed) */
1046   ED_objects_recalculate_paths(C, scene, false);
1047
1048   /* notifiers for updates */
1049   WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
1050
1051   return OPERATOR_FINISHED;
1052 }
1053
1054 void OBJECT_OT_paths_update(wmOperatorType *ot)
1055 {
1056   /* identifiers */
1057   ot->name = "Update Object Paths";
1058   ot->idname = "OBJECT_OT_paths_update";
1059   ot->description = "Recalculate paths for selected objects";
1060
1061   /* api callbakcs */
1062   ot->exec = object_update_paths_exec;
1063   ot->poll = object_update_paths_poll;
1064
1065   /* flags */
1066   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1067 }
1068
1069 /* --------- */
1070
1071 /* Helper for ED_objects_clear_paths() */
1072 static void object_clear_mpath(Object *ob)
1073 {
1074   if (ob->mpath) {
1075     animviz_free_motionpath(ob->mpath);
1076     ob->mpath = NULL;
1077     ob->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
1078
1079     /* tag object for copy on write - so removed paths don't still show */
1080     DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
1081   }
1082 }
1083
1084 /* Clear motion paths for all objects */
1085 void ED_objects_clear_paths(bContext *C, bool only_selected)
1086 {
1087   if (only_selected) {
1088     /* loop over all selected + sedtiable objects in scene */
1089     CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
1090       object_clear_mpath(ob);
1091     }
1092     CTX_DATA_END;
1093   }
1094   else {
1095     /* loop over all edtiable objects in scene */
1096     CTX_DATA_BEGIN (C, Object *, ob, editable_objects) {
1097       object_clear_mpath(ob);
1098     }
1099     CTX_DATA_END;
1100   }
1101 }
1102
1103 /* operator callback for this */
1104 static int object_clear_paths_exec(bContext *C, wmOperator *op)
1105 {
1106   bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
1107
1108   /* use the backend function for this */
1109   ED_objects_clear_paths(C, only_selected);
1110
1111   /* notifiers for updates */
1112   WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
1113
1114   return OPERATOR_FINISHED;
1115 }
1116
1117 /* operator callback/wrapper */
1118 static int object_clear_paths_invoke(bContext *C, wmOperator *op, const wmEvent *evt)
1119 {
1120   if ((evt->shift) && !RNA_struct_property_is_set(op->ptr, "only_selected")) {
1121     RNA_boolean_set(op->ptr, "only_selected", true);
1122   }
1123   return object_clear_paths_exec(C, op);
1124 }
1125
1126 void OBJECT_OT_paths_clear(wmOperatorType *ot)
1127 {
1128   /* identifiers */
1129   ot->name = "Clear Object Paths";
1130   ot->idname = "OBJECT_OT_paths_clear";
1131   ot->description = "Clear path caches for all objects, hold Shift key for selected objects only";
1132
1133   /* api callbacks */
1134   ot->invoke = object_clear_paths_invoke;
1135   ot->exec = object_clear_paths_exec;
1136   ot->poll = ED_operator_object_active_editable;
1137
1138   /* flags */
1139   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1140
1141   /* properties */
1142   ot->prop = RNA_def_boolean(
1143       ot->srna, "only_selected", false, "Only Selected", "Only clear paths from selected objects");
1144   RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
1145 }
1146
1147 /* --------- */
1148
1149 static int object_update_paths_range_exec(bContext *C, wmOperator *UNUSED(op))
1150 {
1151   Scene *scene = CTX_data_scene(C);
1152
1153   /* loop over all edtiable objects in scene */
1154   CTX_DATA_BEGIN (C, Object *, ob, editable_objects) {
1155     /* use Preview Range or Full Frame Range - whichever is in use */
1156     ob->avs.path_sf = PSFRA;
1157     ob->avs.path_ef = PEFRA;
1158
1159     /* tag for updates */
1160     DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
1161     WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
1162   }
1163   CTX_DATA_END;
1164
1165   return OPERATOR_FINISHED;
1166 }
1167
1168 void OBJECT_OT_paths_range_update(wmOperatorType *ot)
1169 {
1170   /* identifiers */
1171   ot->name = "Update Range from Scene";
1172   ot->idname = "OBJECT_OT_paths_range_update";
1173   ot->description = "Update frame range for motion paths from the Scene's current frame range";
1174
1175   /* callbacks */
1176   ot->exec = object_update_paths_range_exec;
1177   ot->poll = ED_operator_object_active_editable;
1178
1179   /* flags */
1180   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1181 }
1182
1183 /********************** Smooth/Flat *********************/
1184
1185 static int shade_smooth_exec(bContext *C, wmOperator *op)
1186 {
1187   ID *data;
1188   Curve *cu;
1189   Nurb *nu;
1190   int clear = (STREQ(op->idname, "OBJECT_OT_shade_flat"));
1191   bool done = false, linked_data = false;
1192
1193   CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
1194     data = ob->data;
1195
1196     if (data && ID_IS_LINKED(data)) {
1197       linked_data = true;
1198       continue;
1199     }
1200
1201     if (ob->type == OB_MESH) {
1202       BKE_mesh_smooth_flag_set(ob, !clear);
1203
1204       BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
1205       DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1206       WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
1207
1208       done = true;
1209     }
1210     else if (ELEM(ob->type, OB_SURF, OB_CURVE)) {
1211       cu = ob->data;
1212
1213       for (nu = cu->nurb.first; nu; nu = nu->next) {
1214         if (!clear) {
1215           nu->flag |= ME_SMOOTH;
1216         }
1217         else {
1218           nu->flag &= ~ME_SMOOTH;
1219         }
1220       }
1221
1222       DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1223       WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
1224
1225       done = true;
1226     }
1227   }
1228   CTX_DATA_END;
1229
1230   if (linked_data) {
1231     BKE_report(op->reports, RPT_WARNING, "Can't edit linked mesh or curve data");
1232   }
1233
1234   return (done) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1235 }
1236
1237 static bool shade_poll(bContext *C)
1238 {
1239   return (CTX_data_edit_object(C) == NULL);
1240 }
1241
1242 void OBJECT_OT_shade_flat(wmOperatorType *ot)
1243 {
1244   /* identifiers */
1245   ot->name = "Shade Flat";
1246   ot->description = "Render and display faces uniform, using Face Normals";
1247   ot->idname = "OBJECT_OT_shade_flat";
1248
1249   /* api callbacks */
1250   ot->poll = shade_poll;
1251   ot->exec = shade_smooth_exec;
1252
1253   /* flags */
1254   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1255 }
1256
1257 void OBJECT_OT_shade_smooth(wmOperatorType *ot)
1258 {
1259   /* identifiers */
1260   ot->name = "Shade Smooth";
1261   ot->description = "Render and display faces smooth, using interpolated Vertex Normals";
1262   ot->idname = "OBJECT_OT_shade_smooth";
1263
1264   /* api callbacks */
1265   ot->poll = shade_poll;
1266   ot->exec = shade_smooth_exec;
1267
1268   /* flags */
1269   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1270 }
1271
1272 /* ********************** */
1273
1274 static const EnumPropertyItem *object_mode_set_itemsf(bContext *C,
1275                                                       PointerRNA *UNUSED(ptr),
1276                                                       PropertyRNA *UNUSED(prop),
1277                                                       bool *r_free)
1278 {
1279   const EnumPropertyItem *input = rna_enum_object_mode_items;
1280   EnumPropertyItem *item = NULL;
1281   Object *ob;
1282   int totitem = 0;
1283
1284   if (!C) { /* needed for docs */
1285     return rna_enum_object_mode_items;
1286   }
1287
1288   ob = CTX_data_active_object(C);
1289   if (ob) {
1290     const bool use_mode_particle_edit = (BLI_listbase_is_empty(&ob->particlesystem) == false) ||
1291                                         (ob->soft != NULL) ||
1292                                         (modifiers_findByType(ob, eModifierType_Cloth) != NULL);
1293     while (input->identifier) {
1294       if ((input->value == OB_MODE_EDIT && OB_TYPE_SUPPORT_EDITMODE(ob->type)) ||
1295           (input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) ||
1296           (input->value == OB_MODE_PARTICLE_EDIT && use_mode_particle_edit) ||
1297           (ELEM(input->value,
1298                 OB_MODE_SCULPT,
1299                 OB_MODE_VERTEX_PAINT,
1300                 OB_MODE_WEIGHT_PAINT,
1301                 OB_MODE_TEXTURE_PAINT) &&
1302            (ob->type == OB_MESH)) ||
1303           (ELEM(input->value,
1304                 OB_MODE_EDIT_GPENCIL,
1305                 OB_MODE_PAINT_GPENCIL,
1306                 OB_MODE_SCULPT_GPENCIL,
1307                 OB_MODE_WEIGHT_GPENCIL) &&
1308            (ob->type == OB_GPENCIL)) ||
1309           (input->value == OB_MODE_OBJECT)) {
1310         RNA_enum_item_add(&item, &totitem, input);
1311       }
1312       input++;
1313     }
1314   }
1315   else {
1316     /* We need at least this one! */
1317     RNA_enum_items_add_value(&item, &totitem, input, OB_MODE_OBJECT);
1318   }
1319
1320   RNA_enum_item_end(&item, &totitem);
1321
1322   *r_free = true;
1323
1324   return item;
1325 }
1326
1327 static bool object_mode_set_poll(bContext *C)
1328 {
1329   /* Since Grease Pencil editmode is also handled here,
1330    * we have a special exception for allowing this operator
1331    * to still work in that case when there's no active object
1332    * so that users can exit editmode this way as per normal.
1333    */
1334   if (ED_operator_object_active_editable(C)) {
1335     return true;
1336   }
1337   else {
1338     return (CTX_data_gpencil_data(C) != NULL);
1339   }
1340 }
1341
1342 static int object_mode_set_exec(bContext *C, wmOperator *op)
1343 {
1344   bool use_submode = STREQ(op->idname, "OBJECT_OT_mode_set_or_submode");
1345   Object *ob = CTX_data_active_object(C);
1346   eObjectMode mode = RNA_enum_get(op->ptr, "mode");
1347   eObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT;
1348   const bool toggle = RNA_boolean_get(op->ptr, "toggle");
1349
1350   if (use_submode) {
1351     /* When not changing modes use submodes, see: T55162. */
1352     if (toggle == false) {
1353       if (mode == restore_mode) {
1354         switch (mode) {
1355           case OB_MODE_EDIT:
1356             WM_menu_name_call(C, "VIEW3D_MT_edit_mesh_select_mode", WM_OP_INVOKE_REGION_WIN);
1357             return OPERATOR_INTERFACE;
1358           default:
1359             break;
1360         }
1361       }
1362     }
1363   }
1364
1365   /* by default the operator assume is a mesh, but if gp object change mode */
1366   if ((ob != NULL) && (ob->type == OB_GPENCIL) && (mode == OB_MODE_EDIT)) {
1367     mode = OB_MODE_EDIT_GPENCIL;
1368   }
1369
1370   if (!ob || !ED_object_mode_compat_test(ob, mode)) {
1371     return OPERATOR_PASS_THROUGH;
1372   }
1373
1374   if (ob->mode != mode) {
1375     /* we should be able to remove this call, each operator calls  */
1376     ED_object_mode_compat_set(C, ob, mode, op->reports);
1377   }
1378
1379   /* Exit current mode if it's not the mode we're setting */
1380   if (mode != OB_MODE_OBJECT && (ob->mode != mode || toggle)) {
1381     /* Enter new mode */
1382     ED_object_mode_toggle(C, mode);
1383   }
1384
1385   if (toggle) {
1386     /* Special case for Object mode! */
1387     if (mode == OB_MODE_OBJECT && restore_mode == OB_MODE_OBJECT &&
1388         ob->restore_mode != OB_MODE_OBJECT) {
1389       ED_object_mode_toggle(C, ob->restore_mode);
1390     }
1391     else if (ob->mode == mode) {
1392       /* For toggling, store old mode so we know what to go back to */
1393       ob->restore_mode = restore_mode;
1394     }
1395     else if (ob->restore_mode != OB_MODE_OBJECT && ob->restore_mode != mode) {
1396       ED_object_mode_toggle(C, ob->restore_mode);
1397     }
1398   }
1399
1400   /* if type is OB_GPENCIL, set cursor mode */
1401   if ((ob) && (ob->type == OB_GPENCIL)) {
1402     if (ob->data) {
1403       bGPdata *gpd = (bGPdata *)ob->data;
1404       ED_gpencil_setup_modes(C, gpd, ob->mode);
1405     }
1406   }
1407
1408   return OPERATOR_FINISHED;
1409 }
1410
1411 void OBJECT_OT_mode_set(wmOperatorType *ot)
1412 {
1413   PropertyRNA *prop;
1414
1415   /* identifiers */
1416   ot->name = "Set Object Mode";
1417   ot->description = "Sets the object interaction mode";
1418   ot->idname = "OBJECT_OT_mode_set";
1419
1420   /* api callbacks */
1421   ot->exec = object_mode_set_exec;
1422
1423   ot->poll = object_mode_set_poll;  // ED_operator_object_active_editable;
1424
1425   /* flags */
1426   ot->flag = 0; /* no register/undo here, leave it to operators being called */
1427
1428   ot->prop = RNA_def_enum(
1429       ot->srna, "mode", rna_enum_object_mode_items, OB_MODE_OBJECT, "Mode", "");
1430   RNA_def_enum_funcs(ot->prop, object_mode_set_itemsf);
1431   RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
1432
1433   prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "");
1434   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1435 }
1436
1437 void OBJECT_OT_mode_set_or_submode(wmOperatorType *ot)
1438 {
1439   PropertyRNA *prop;
1440
1441   /* identifiers */
1442   ot->name = "Set Object Mode or Submode";
1443   ot->description = "Sets the object interaction mode";
1444   ot->idname = "OBJECT_OT_mode_set_or_submode";
1445
1446   /* api callbacks */
1447   ot->exec = object_mode_set_exec;
1448
1449   ot->poll = object_mode_set_poll;  // ED_operator_object_active_editable;
1450
1451   /* flags */
1452   ot->flag = 0; /* no register/undo here, leave it to operators being called */
1453
1454   ot->prop = RNA_def_enum(
1455       ot->srna, "mode", rna_enum_object_mode_items, OB_MODE_OBJECT, "Mode", "");
1456   RNA_def_enum_funcs(ot->prop, object_mode_set_itemsf);
1457   RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
1458
1459   prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "");
1460   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1461 }
1462
1463 static bool move_to_collection_poll(bContext *C)
1464 {
1465   if (CTX_wm_space_outliner(C) != NULL) {
1466     return ED_outliner_collections_editor_poll(C);
1467   }
1468   else {
1469     View3D *v3d = CTX_wm_view3d(C);
1470
1471     if (v3d && v3d->localvd) {
1472       return false;
1473     }
1474
1475     return ED_operator_object_active_editable(C);
1476   }
1477 }
1478
1479 static int move_to_collection_exec(bContext *C, wmOperator *op)
1480 {
1481   Main *bmain = CTX_data_main(C);
1482   Scene *scene = CTX_data_scene(C);
1483   PropertyRNA *prop = RNA_struct_find_property(op->ptr, "collection_index");
1484   const bool is_link = STREQ(op->idname, "OBJECT_OT_link_to_collection");
1485   const bool is_new = RNA_boolean_get(op->ptr, "is_new");
1486   Collection *collection;
1487   ListBase objects = {NULL};
1488
1489   if (!RNA_property_is_set(op->ptr, prop)) {
1490     BKE_report(op->reports, RPT_ERROR, "No collection selected");
1491     return OPERATOR_CANCELLED;
1492   }
1493
1494   int collection_index = RNA_property_int_get(op->ptr, prop);
1495   collection = BKE_collection_from_index(CTX_data_scene(C), collection_index);
1496   if (collection == NULL) {
1497     BKE_report(op->reports, RPT_ERROR, "Unexpected error, collection not found");
1498     return OPERATOR_CANCELLED;
1499   }
1500
1501   if (CTX_wm_space_outliner(C) != NULL) {
1502     ED_outliner_selected_objects_get(C, &objects);
1503   }
1504   else {
1505     CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
1506       BLI_addtail(&objects, BLI_genericNodeN(ob));
1507     }
1508     CTX_DATA_END;
1509   }
1510
1511   if (is_new) {
1512     char new_collection_name[MAX_NAME];
1513     RNA_string_get(op->ptr, "new_collection_name", new_collection_name);
1514     collection = BKE_collection_add(bmain, collection, new_collection_name);
1515   }
1516
1517   Object *single_object = BLI_listbase_is_single(&objects) ? ((LinkData *)objects.first)->data :
1518                                                              NULL;
1519
1520   if ((single_object != NULL) && is_link &&
1521       BLI_findptr(&collection->gobject, single_object, offsetof(CollectionObject, ob))) {
1522     BKE_reportf(op->reports,
1523                 RPT_ERROR,
1524                 "%s already in %s",
1525                 single_object->id.name + 2,
1526                 collection->id.name + 2);
1527     BLI_freelistN(&objects);
1528     return OPERATOR_CANCELLED;
1529   }
1530
1531   for (LinkData *link = objects.first; link; link = link->next) {
1532     Object *ob = link->data;
1533
1534     if (!is_link) {
1535       BKE_collection_object_move(bmain, scene, collection, NULL, ob);
1536     }
1537     else {
1538       BKE_collection_object_add(bmain, collection, ob);
1539     }
1540   }
1541   BLI_freelistN(&objects);
1542
1543   BKE_reportf(op->reports,
1544               RPT_INFO,
1545               "%s %s to %s",
1546               (single_object != NULL) ? single_object->id.name + 2 : "Objects",
1547               is_link ? "linked" : "moved",
1548               collection->id.name + 2);
1549
1550   DEG_relations_tag_update(bmain);
1551   DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
1552
1553   WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
1554   WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
1555   WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
1556
1557   return OPERATOR_FINISHED;
1558 }
1559
1560 struct MoveToCollectionData {
1561   struct MoveToCollectionData *next, *prev;
1562   int index;
1563   struct Collection *collection;
1564   struct ListBase submenus;
1565   PointerRNA ptr;
1566   struct wmOperatorType *ot;
1567 };
1568
1569 static int move_to_collection_menus_create(wmOperator *op, MoveToCollectionData *menu)
1570 {
1571   int index = menu->index;
1572   for (CollectionChild *child = menu->collection->children.first; child != NULL;
1573        child = child->next) {
1574     Collection *collection = child->collection;
1575     MoveToCollectionData *submenu = MEM_callocN(sizeof(MoveToCollectionData),
1576                                                 "MoveToCollectionData submenu - expected memleak");
1577     BLI_addtail(&menu->submenus, submenu);
1578     submenu->collection = collection;
1579     submenu->index = ++index;
1580     index = move_to_collection_menus_create(op, submenu);
1581     submenu->ot = op->type;
1582   }
1583   return index;
1584 }
1585
1586 static void move_to_collection_menus_free_recursive(MoveToCollectionData *menu)
1587 {
1588   for (MoveToCollectionData *submenu = menu->submenus.first; submenu != NULL;
1589        submenu = submenu->next) {
1590     move_to_collection_menus_free_recursive(submenu);
1591   }
1592   BLI_freelistN(&menu->submenus);
1593 }
1594
1595 static void move_to_collection_menus_free(MoveToCollectionData **menu)
1596 {
1597   if (*menu == NULL) {
1598     return;
1599   }
1600
1601   move_to_collection_menus_free_recursive(*menu);
1602   MEM_freeN(*menu);
1603   *menu = NULL;
1604 }
1605
1606 static void move_to_collection_menu_create(bContext *UNUSED(C), uiLayout *layout, void *menu_v)
1607 {
1608   MoveToCollectionData *menu = menu_v;
1609   const char *name = BKE_collection_ui_name_get(menu->collection);
1610
1611   UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
1612   uiItemIntO(layout, name, ICON_NONE, menu->ot->idname, "collection_index", menu->index);
1613   uiItemS(layout);
1614
1615   for (MoveToCollectionData *submenu = menu->submenus.first; submenu != NULL;
1616        submenu = submenu->next) {
1617     move_to_collection_menus_items(layout, submenu);
1618   }
1619
1620   uiItemS(layout);
1621
1622   WM_operator_properties_create_ptr(&menu->ptr, menu->ot);
1623   RNA_int_set(&menu->ptr, "collection_index", menu->index);
1624   RNA_boolean_set(&menu->ptr, "is_new", true);
1625
1626   uiItemFullO_ptr(
1627       layout, menu->ot, "New Collection", ICON_ADD, menu->ptr.data, WM_OP_INVOKE_DEFAULT, 0, NULL);
1628 }
1629
1630 static void move_to_collection_menus_items(uiLayout *layout, MoveToCollectionData *menu)
1631 {
1632   if (BLI_listbase_is_empty(&menu->submenus)) {
1633     uiItemIntO(layout,
1634                menu->collection->id.name + 2,
1635                ICON_NONE,
1636                menu->ot->idname,
1637                "collection_index",
1638                menu->index);
1639   }
1640   else {
1641     uiItemMenuF(
1642         layout, menu->collection->id.name + 2, ICON_NONE, move_to_collection_menu_create, menu);
1643   }
1644 }
1645
1646 /* This is allocated statically because we need this available for the menus creation callback. */
1647 static MoveToCollectionData *master_collection_menu = NULL;
1648
1649 static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1650 {
1651   Scene *scene = CTX_data_scene(C);
1652
1653   /* Reset the menus data for the current master collection, and free previously allocated data. */
1654   move_to_collection_menus_free(&master_collection_menu);
1655
1656   PropertyRNA *prop;
1657   prop = RNA_struct_find_property(op->ptr, "collection_index");
1658   if (RNA_property_is_set(op->ptr, prop)) {
1659     int collection_index = RNA_property_int_get(op->ptr, prop);
1660
1661     if (RNA_boolean_get(op->ptr, "is_new")) {
1662       prop = RNA_struct_find_property(op->ptr, "new_collection_name");
1663       if (!RNA_property_is_set(op->ptr, prop)) {
1664         char name[MAX_NAME];
1665         Collection *collection;
1666
1667         collection = BKE_collection_from_index(scene, collection_index);
1668         BKE_collection_new_name_get(collection, name);
1669
1670         RNA_property_string_set(op->ptr, prop, name);
1671         return WM_operator_props_dialog_popup(C, op, 200, 100);
1672       }
1673     }
1674     return move_to_collection_exec(C, op);
1675   }
1676
1677   Collection *master_collection = BKE_collection_master(scene);
1678
1679   /* We need the data to be allocated so it's available during menu drawing.
1680    * Technically we could use wmOperator->customdata. However there is no free callback
1681    * called to an operator that exit with OPERATOR_INTERFACE to launch a menu.
1682    *
1683    * So we are left with a memory that will necessarily leak. It's a small leak though.*/
1684   if (master_collection_menu == NULL) {
1685     master_collection_menu = MEM_callocN(sizeof(MoveToCollectionData),
1686                                          "MoveToCollectionData menu - expected eventual memleak");
1687   }
1688
1689   master_collection_menu->collection = master_collection;
1690   master_collection_menu->ot = op->type;
1691   move_to_collection_menus_create(op, master_collection_menu);
1692
1693   uiPopupMenu *pup;
1694   uiLayout *layout;
1695
1696   /* Build the menus. */
1697   const char *title = CTX_IFACE_(op->type->translation_context, op->type->name);
1698   pup = UI_popup_menu_begin(C, title, ICON_NONE);
1699   layout = UI_popup_menu_layout(pup);
1700
1701   uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
1702
1703   move_to_collection_menu_create(C, layout, master_collection_menu);
1704
1705   UI_popup_menu_end(C, pup);
1706
1707   return OPERATOR_INTERFACE;
1708 }
1709
1710 void OBJECT_OT_move_to_collection(wmOperatorType *ot)
1711 {
1712   PropertyRNA *prop;
1713
1714   /* identifiers */
1715   ot->name = "Move to Collection";
1716   ot->description = "Move objects to a collection";
1717   ot->idname = "OBJECT_OT_move_to_collection";
1718
1719   /* api callbacks */
1720   ot->exec = move_to_collection_exec;
1721   ot->invoke = move_to_collection_invoke;
1722   ot->poll = move_to_collection_poll;
1723
1724   /* flags */
1725   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1726
1727   prop = RNA_def_int(ot->srna,
1728                      "collection_index",
1729                      COLLECTION_INVALID_INDEX,
1730                      COLLECTION_INVALID_INDEX,
1731                      INT_MAX,
1732                      "Collection Index",
1733                      "Index of the collection to move to",
1734                      0,
1735                      INT_MAX);
1736   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
1737   prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Move objects to a new collection");
1738   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
1739   prop = RNA_def_string(ot->srna,
1740                         "new_collection_name",
1741                         NULL,
1742                         MAX_NAME,
1743                         "Name",
1744                         "Name of the newly added collection");
1745   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1746   ot->prop = prop;
1747 }
1748
1749 void OBJECT_OT_link_to_collection(wmOperatorType *ot)
1750 {
1751   PropertyRNA *prop;
1752
1753   /* identifiers */
1754   ot->name = "Link to Collection";
1755   ot->description = "Link objects to a collection";
1756   ot->idname = "OBJECT_OT_link_to_collection";
1757
1758   /* api callbacks */
1759   ot->exec = move_to_collection_exec;
1760   ot->invoke = move_to_collection_invoke;
1761   ot->poll = move_to_collection_poll;
1762
1763   /* flags */
1764   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1765
1766   prop = RNA_def_int(ot->srna,
1767                      "collection_index",
1768                      COLLECTION_INVALID_INDEX,
1769                      COLLECTION_INVALID_INDEX,
1770                      INT_MAX,
1771                      "Collection Index",
1772                      "Index of the collection to move to",
1773                      0,
1774                      INT_MAX);
1775   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
1776   prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Move objects to a new collection");
1777   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
1778   prop = RNA_def_string(ot->srna,
1779                         "new_collection_name",
1780                         NULL,
1781                         MAX_NAME,
1782                         "Name",
1783                         "Name of the newly added collection");
1784   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1785   ot->prop = prop;
1786 }