Cleanup: style, use braces for editors
[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   if (BKE_layer_collection_isolate(scene, view_layer, lc, extend)) {
292     DEG_relations_tag_update(CTX_data_main(C));
293   }
294
295   WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
296
297   return OPERATOR_FINISHED;
298 }
299
300 #define COLLECTION_INVALID_INDEX -1
301
302 void ED_collection_hide_menu_draw(const bContext *C, uiLayout *layout)
303 {
304   ViewLayer *view_layer = CTX_data_view_layer(C);
305   LayerCollection *lc_scene = view_layer->layer_collections.first;
306
307   uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
308
309   for (LayerCollection *lc = lc_scene->layer_collections.first; lc; lc = lc->next) {
310     int index = BKE_layer_collection_findindex(view_layer, lc);
311     uiLayout *row = uiLayoutRow(layout, false);
312
313     if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
314       continue;
315     }
316
317     if (lc->collection->flag & COLLECTION_RESTRICT_VIEW) {
318       continue;
319     }
320
321     int icon = ICON_NONE;
322     if (BKE_layer_collection_has_selected_objects(view_layer, lc)) {
323       icon = ICON_LAYER_ACTIVE;
324     }
325     else if (lc->runtime_flag & LAYER_COLLECTION_HAS_OBJECTS) {
326       icon = ICON_LAYER_USED;
327     }
328
329     uiItemIntO(row,
330                lc->collection->id.name + 2,
331                icon,
332                "OBJECT_OT_hide_collection",
333                "collection_index",
334                index);
335   }
336 }
337
338 static int object_hide_collection_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
339 {
340   /* Immediately execute if collection index was specified. */
341   int index = RNA_int_get(op->ptr, "collection_index");
342   if (index != COLLECTION_INVALID_INDEX) {
343     return object_hide_collection_exec(C, op);
344   }
345
346   /* Open popup menu. */
347   const char *title = CTX_IFACE_(op->type->translation_context, op->type->name);
348   uiPopupMenu *pup = UI_popup_menu_begin(C, title, ICON_GROUP);
349   uiLayout *layout = UI_popup_menu_layout(pup);
350
351   ED_collection_hide_menu_draw(C, layout);
352
353   UI_popup_menu_end(C, pup);
354
355   return OPERATOR_INTERFACE;
356 }
357
358 void OBJECT_OT_hide_collection(wmOperatorType *ot)
359 {
360   /* identifiers */
361   ot->name = "Hide Collection";
362   ot->description = "Show only objects in collection (Shift to extend)";
363   ot->idname = "OBJECT_OT_hide_collection";
364
365   /* api callbacks */
366   ot->exec = object_hide_collection_exec;
367   ot->invoke = object_hide_collection_invoke;
368   ot->poll = ED_operator_view3d_active;
369
370   /* flags */
371   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
372
373   /* Properties. */
374   PropertyRNA *prop;
375   prop = RNA_def_int(ot->srna,
376                      "collection_index",
377                      COLLECTION_INVALID_INDEX,
378                      COLLECTION_INVALID_INDEX,
379                      INT_MAX,
380                      "Collection Index",
381                      "Index of the collection to change visibility",
382                      0,
383                      INT_MAX);
384   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
385   prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "Toggle visibility");
386   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
387 }
388
389 /* ******************* toggle editmode operator  ***************** */
390
391 static bool mesh_needs_keyindex(Main *bmain, const Mesh *me)
392 {
393   if (me->key) {
394     return false; /* will be added */
395   }
396
397   for (const Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
398     if ((ob->parent) && (ob->parent->data == me) && ELEM(ob->partype, PARVERT1, PARVERT3)) {
399       return true;
400     }
401     if (ob->data == me) {
402       for (const ModifierData *md = ob->modifiers.first; md; md = md->next) {
403         if (md->type == eModifierType_Hook) {
404           return true;
405         }
406       }
407     }
408   }
409   return false;
410 }
411
412 /**
413  * Load EditMode data back into the object,
414  * optionally freeing the editmode data.
415  */
416 static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool freedata)
417 {
418   if (obedit == NULL) {
419     return false;
420   }
421
422   if (obedit->type == OB_MESH) {
423     Mesh *me = obedit->data;
424     if (me->edit_mesh == NULL) {
425       return false;
426     }
427
428     if (me->edit_mesh->bm->totvert > MESH_MAX_VERTS) {
429       error("Too many vertices");
430       return false;
431     }
432
433     EDBM_mesh_load(bmain, obedit);
434
435     if (freedata) {
436       EDBM_mesh_free(me->edit_mesh);
437       MEM_freeN(me->edit_mesh);
438       me->edit_mesh = NULL;
439     }
440     /* will be recalculated as needed. */
441     {
442       ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
443       ED_mesh_mirror_topo_table(NULL, NULL, 'e');
444     }
445   }
446   else if (obedit->type == OB_ARMATURE) {
447     const bArmature *arm = obedit->data;
448     if (arm->edbo == NULL) {
449       return false;
450     }
451     ED_armature_from_edit(bmain, obedit->data);
452     if (freedata) {
453       ED_armature_edit_free(obedit->data);
454     }
455     /* TODO(sergey): Pose channels might have been changed, so need
456      * to inform dependency graph about this. But is it really the
457      * best place to do this?
458      */
459     DEG_relations_tag_update(bmain);
460   }
461   else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
462     const Curve *cu = obedit->data;
463     if (cu->editnurb == NULL) {
464       return false;
465     }
466     ED_curve_editnurb_load(bmain, obedit);
467     if (freedata) {
468       ED_curve_editnurb_free(obedit);
469     }
470   }
471   else if (obedit->type == OB_FONT) {
472     const Curve *cu = obedit->data;
473     if (cu->editfont == NULL) {
474       return false;
475     }
476     ED_curve_editfont_load(obedit);
477     if (freedata) {
478       ED_curve_editfont_free(obedit);
479     }
480   }
481   else if (obedit->type == OB_LATTICE) {
482     const Lattice *lt = obedit->data;
483     if (lt->editlatt == NULL) {
484       return false;
485     }
486     BKE_editlattice_load(obedit);
487     if (freedata) {
488       BKE_editlattice_free(obedit);
489     }
490   }
491   else if (obedit->type == OB_MBALL) {
492     const MetaBall *mb = obedit->data;
493     if (mb->editelems == NULL) {
494       return false;
495     }
496     ED_mball_editmball_load(obedit);
497     if (freedata) {
498       ED_mball_editmball_free(obedit);
499     }
500   }
501
502   return true;
503 }
504
505 bool ED_object_editmode_load(Main *bmain, Object *obedit)
506 {
507   return ED_object_editmode_load_ex(bmain, obedit, false);
508 }
509
510 /**
511  * \param flag:
512  * - If #EM_FREEDATA isn't in the flag, use ED_object_editmode_load directly.
513  */
514 bool ED_object_editmode_exit_ex(Main *bmain, Scene *scene, Object *obedit, int flag)
515 {
516   const bool freedata = (flag & EM_FREEDATA) != 0;
517
518   if (ED_object_editmode_load_ex(bmain, obedit, freedata) == false) {
519     /* in rare cases (background mode) its possible active object
520      * is flagged for editmode, without 'obedit' being set [#35489] */
521     if (UNLIKELY(obedit && obedit->mode & OB_MODE_EDIT)) {
522       obedit->mode &= ~OB_MODE_EDIT;
523     }
524     return true;
525   }
526
527   /* freedata only 0 now on file saves and render */
528   if (freedata) {
529     ListBase pidlist;
530     PTCacheID *pid;
531
532     /* flag object caches as outdated */
533     BKE_ptcache_ids_from_object(&pidlist, obedit, scene, 0);
534     for (pid = pidlist.first; pid; pid = pid->next) {
535       /* particles don't need reset on geometry change */
536       if (pid->type != PTCACHE_TYPE_PARTICLES) {
537         pid->cache->flag |= PTCACHE_OUTDATED;
538       }
539     }
540     BLI_freelistN(&pidlist);
541
542     BKE_particlesystem_reset_all(obedit);
543     BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED);
544
545     /* also flush ob recalc, doesn't take much overhead, but used for particles */
546     DEG_id_tag_update(&obedit->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
547
548     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
549
550     obedit->mode &= ~OB_MODE_EDIT;
551   }
552
553   return (obedit->mode & OB_MODE_EDIT) == 0;
554 }
555
556 bool ED_object_editmode_exit(bContext *C, int flag)
557 {
558   Main *bmain = CTX_data_main(C);
559   Scene *scene = CTX_data_scene(C);
560   Object *obedit = CTX_data_edit_object(C);
561   return ED_object_editmode_exit_ex(bmain, scene, obedit, flag);
562 }
563
564 bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag)
565 {
566   bool ok = false;
567
568   if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob)) {
569     return false;
570   }
571
572   /* this checks actual object->data, for cases when other scenes have it in editmode context */
573   if (BKE_object_is_in_editmode(ob)) {
574     return true;
575   }
576
577   if (BKE_object_obdata_is_libdata(ob)) {
578     error_libdata();
579     return false;
580   }
581
582   ob->restore_mode = ob->mode;
583
584   ob->mode = OB_MODE_EDIT;
585
586   if (ob->type == OB_MESH) {
587     BMEditMesh *em;
588     ok = 1;
589
590     const bool use_key_index = mesh_needs_keyindex(bmain, ob->data);
591
592     EDBM_mesh_make(ob, scene->toolsettings->selectmode, use_key_index);
593
594     em = BKE_editmesh_from_object(ob);
595     if (LIKELY(em)) {
596       /* order doesn't matter */
597       EDBM_mesh_normals_update(em);
598       BKE_editmesh_tessface_calc(em);
599     }
600
601     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_MESH, NULL);
602   }
603   else if (ob->type == OB_ARMATURE) {
604     ok = 1;
605     ED_armature_to_edit(ob->data);
606     /* to ensure all goes in restposition and without striding */
607
608     /* XXX: should this be ID_RECALC_GEOMETRY? */
609     DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
610
611     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_ARMATURE, scene);
612   }
613   else if (ob->type == OB_FONT) {
614     ok = 1;
615     ED_curve_editfont_make(ob);
616
617     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_TEXT, scene);
618   }
619   else if (ob->type == OB_MBALL) {
620     ok = 1;
621     ED_mball_editmball_make(ob);
622
623     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_MBALL, scene);
624   }
625   else if (ob->type == OB_LATTICE) {
626     ok = 1;
627     BKE_editlattice_make(ob);
628
629     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_LATTICE, scene);
630   }
631   else if (ob->type == OB_SURF || ob->type == OB_CURVE) {
632     ok = 1;
633     ED_curve_editnurb_make(ob);
634
635     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_CURVE, scene);
636   }
637
638   if (ok) {
639     DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
640   }
641   else {
642     if ((flag & EM_NO_CONTEXT) == 0) {
643       ob->mode &= ~OB_MODE_EDIT;
644     }
645     WM_main_add_notifier(NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
646   }
647
648   return (ob->mode & OB_MODE_EDIT) != 0;
649 }
650
651 bool ED_object_editmode_enter(bContext *C, int flag)
652 {
653   Main *bmain = CTX_data_main(C);
654   Scene *scene = CTX_data_scene(C);
655   Object *ob;
656
657   /* Active layer checked here for view3d,
658    * callers that don't want view context can call the extended version. */
659   ob = CTX_data_active_object(C);
660   if ((ob == NULL) || ID_IS_LINKED(ob)) {
661     return false;
662   }
663   return ED_object_editmode_enter_ex(bmain, scene, ob, flag);
664 }
665
666 static int editmode_toggle_exec(bContext *C, wmOperator *op)
667 {
668   struct wmMsgBus *mbus = CTX_wm_message_bus(C);
669   const int mode_flag = OB_MODE_EDIT;
670   const bool is_mode_set = (CTX_data_edit_object(C) != NULL);
671   Main *bmain = CTX_data_main(C);
672   Scene *scene = CTX_data_scene(C);
673   ViewLayer *view_layer = CTX_data_view_layer(C);
674   View3D *v3d = CTX_wm_view3d(C);
675   Object *obact = OBACT(view_layer);
676
677   if (!is_mode_set) {
678     if (!ED_object_mode_compat_set(C, obact, mode_flag, op->reports)) {
679       return OPERATOR_CANCELLED;
680     }
681   }
682
683   if (!is_mode_set) {
684     ED_object_editmode_enter(C, 0);
685     if (obact->mode & mode_flag) {
686       FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob) {
687         if ((ob != obact) && (ob->type == obact->type)) {
688           ED_object_editmode_enter_ex(bmain, scene, ob, EM_NO_CONTEXT);
689         }
690       }
691       FOREACH_SELECTED_OBJECT_END;
692     }
693   }
694   else {
695     ED_object_editmode_exit(C, EM_FREEDATA);
696     if ((obact->mode & mode_flag) == 0) {
697       FOREACH_OBJECT_BEGIN (view_layer, ob) {
698         if ((ob != obact) && (ob->type == obact->type)) {
699           ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
700         }
701       }
702       FOREACH_OBJECT_END;
703     }
704   }
705
706   ED_space_image_uv_sculpt_update(bmain, CTX_wm_manager(C), scene);
707
708   WM_msg_publish_rna_prop(mbus, &obact->id, obact, Object, mode);
709
710   if (G.background == false) {
711     WM_toolsystem_update_from_context_view3d(C);
712   }
713
714   return OPERATOR_FINISHED;
715 }
716
717 static bool editmode_toggle_poll(bContext *C)
718 {
719   Object *ob = CTX_data_active_object(C);
720
721   /* covers proxies too */
722   if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob->data)) {
723     return 0;
724   }
725
726   /* if hidden but in edit mode, we still display */
727   if ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT)) {
728     return 0;
729   }
730
731   return OB_TYPE_SUPPORT_EDITMODE(ob->type);
732 }
733
734 void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
735 {
736
737   /* identifiers */
738   ot->name = "Toggle Editmode";
739   ot->description = "Toggle object's editmode";
740   ot->idname = "OBJECT_OT_editmode_toggle";
741
742   /* api callbacks */
743   ot->exec = editmode_toggle_exec;
744   ot->poll = editmode_toggle_poll;
745
746   /* flags */
747   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
748 }
749
750 /* *************************** */
751
752 static int posemode_exec(bContext *C, wmOperator *op)
753 {
754   struct wmMsgBus *mbus = CTX_wm_message_bus(C);
755   Base *base = CTX_data_active_base(C);
756
757   /* If the base is NULL it means we have an active object, but the object itself is hidden. */
758   if (base == NULL) {
759     return OPERATOR_CANCELLED;
760   }
761
762   Object *obact = base->object;
763   const int mode_flag = OB_MODE_POSE;
764   bool is_mode_set = (obact->mode & mode_flag) != 0;
765
766   if (!is_mode_set) {
767     if (!ED_object_mode_compat_set(C, obact, mode_flag, op->reports)) {
768       return OPERATOR_CANCELLED;
769     }
770   }
771
772   if (obact->type != OB_ARMATURE) {
773     return OPERATOR_PASS_THROUGH;
774   }
775
776   if (obact == CTX_data_edit_object(C)) {
777     ED_object_editmode_exit(C, EM_FREEDATA);
778     is_mode_set = false;
779   }
780
781   if (is_mode_set) {
782     bool ok = ED_object_posemode_exit(C, obact);
783     if (ok) {
784       struct Main *bmain = CTX_data_main(C);
785       ViewLayer *view_layer = CTX_data_view_layer(C);
786       FOREACH_OBJECT_BEGIN (view_layer, ob) {
787         if ((ob != obact) && (ob->type == OB_ARMATURE) && (ob->mode & mode_flag)) {
788           ED_object_posemode_exit_ex(bmain, ob);
789         }
790       }
791       FOREACH_OBJECT_END;
792     }
793   }
794   else {
795     bool ok = ED_object_posemode_enter(C, obact);
796     if (ok) {
797       struct Main *bmain = CTX_data_main(C);
798       ViewLayer *view_layer = CTX_data_view_layer(C);
799       View3D *v3d = CTX_wm_view3d(C);
800       FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob) {
801         if ((ob != obact) && (ob->type == OB_ARMATURE) && (ob->mode == OB_MODE_OBJECT) &&
802             (!ID_IS_LINKED(ob))) {
803           ED_object_posemode_enter_ex(bmain, ob);
804         }
805       }
806       FOREACH_SELECTED_OBJECT_END;
807     }
808   }
809
810   WM_msg_publish_rna_prop(mbus, &obact->id, obact, Object, mode);
811
812   if (G.background == false) {
813     WM_toolsystem_update_from_context_view3d(C);
814   }
815
816   return OPERATOR_FINISHED;
817 }
818
819 void OBJECT_OT_posemode_toggle(wmOperatorType *ot)
820 {
821   /* identifiers */
822   ot->name = "Toggle Pose Mode";
823   ot->idname = "OBJECT_OT_posemode_toggle";
824   ot->description = "Enable or disable posing/selecting bones";
825
826   /* api callbacks */
827   ot->exec = posemode_exec;
828   ot->poll = ED_operator_object_active_editable;
829
830   /* flag */
831   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
832 }
833
834 /* ******************* force field toggle operator ***************** */
835
836 void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object)
837 {
838   PartDeflect *pd = object->pd;
839   ModifierData *md = modifiers_findByType(object, eModifierType_Surface);
840
841   /* add/remove modifier as needed */
842   if (!md) {
843     if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) &&
844         !ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) {
845       if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) {
846         ED_object_modifier_add(NULL, bmain, scene, object, NULL, eModifierType_Surface);
847       }
848     }
849   }
850   else {
851     if (!pd || (pd->shape != PFIELD_SHAPE_SURFACE) ||
852         ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) {
853       ED_object_modifier_remove(NULL, bmain, object, md);
854     }
855   }
856 }
857
858 static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op))
859 {
860   Object *ob = CTX_data_active_object(C);
861
862   if (ob->pd == NULL) {
863     ob->pd = BKE_partdeflect_new(PFIELD_FORCE);
864   }
865   else if (ob->pd->forcefield == 0) {
866     ob->pd->forcefield = PFIELD_FORCE;
867   }
868   else {
869     ob->pd->forcefield = 0;
870   }
871
872   ED_object_check_force_modifiers(CTX_data_main(C), CTX_data_scene(C), ob);
873   WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
874   WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
875
876   return OPERATOR_FINISHED;
877 }
878
879 void OBJECT_OT_forcefield_toggle(wmOperatorType *ot)
880 {
881
882   /* identifiers */
883   ot->name = "Toggle Force Field";
884   ot->description = "Toggle object's force field";
885   ot->idname = "OBJECT_OT_forcefield_toggle";
886
887   /* api callbacks */
888   ot->exec = forcefield_toggle_exec;
889   ot->poll = ED_operator_object_active_editable;
890
891   /* flags */
892   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
893 }
894
895 /* ********************************************** */
896 /* Motion Paths */
897
898 /* For the objects with animation: update paths for those that have got them
899  * This should selectively update paths that exist...
900  *
901  * To be called from various tools that do incremental updates
902  */
903 void ED_objects_recalculate_paths(bContext *C, Scene *scene, bool current_frame_only)
904 {
905   /* Transform doesn't always have context available to do update. */
906   if (C == NULL) {
907     return;
908   }
909
910   Main *bmain = CTX_data_main(C);
911   Depsgraph *depsgraph = CTX_data_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   uiItemIntO(layout, name, ICON_NONE, menu->ot->idname, "collection_index", menu->index);
1612   uiItemS(layout);
1613
1614   for (MoveToCollectionData *submenu = menu->submenus.first; submenu != NULL;
1615        submenu = submenu->next) {
1616     move_to_collection_menus_items(layout, submenu);
1617   }
1618
1619   uiItemS(layout);
1620
1621   WM_operator_properties_create_ptr(&menu->ptr, menu->ot);
1622   RNA_int_set(&menu->ptr, "collection_index", menu->index);
1623   RNA_boolean_set(&menu->ptr, "is_new", true);
1624
1625   uiItemFullO_ptr(
1626       layout, menu->ot, "New Collection", ICON_ADD, menu->ptr.data, WM_OP_INVOKE_DEFAULT, 0, NULL);
1627 }
1628
1629 static void move_to_collection_menus_items(uiLayout *layout, MoveToCollectionData *menu)
1630 {
1631   if (BLI_listbase_is_empty(&menu->submenus)) {
1632     uiItemIntO(layout,
1633                menu->collection->id.name + 2,
1634                ICON_NONE,
1635                menu->ot->idname,
1636                "collection_index",
1637                menu->index);
1638   }
1639   else {
1640     uiItemMenuF(
1641         layout, menu->collection->id.name + 2, ICON_NONE, move_to_collection_menu_create, menu);
1642   }
1643 }
1644
1645 /* This is allocated statically because we need this available for the menus creation callback. */
1646 static MoveToCollectionData *master_collection_menu = NULL;
1647
1648 static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1649 {
1650   Scene *scene = CTX_data_scene(C);
1651
1652   /* Reset the menus data for the current master collection, and free previously allocated data. */
1653   move_to_collection_menus_free(&master_collection_menu);
1654
1655   PropertyRNA *prop;
1656   prop = RNA_struct_find_property(op->ptr, "collection_index");
1657   if (RNA_property_is_set(op->ptr, prop)) {
1658     int collection_index = RNA_property_int_get(op->ptr, prop);
1659
1660     if (RNA_boolean_get(op->ptr, "is_new")) {
1661       prop = RNA_struct_find_property(op->ptr, "new_collection_name");
1662       if (!RNA_property_is_set(op->ptr, prop)) {
1663         char name[MAX_NAME];
1664         Collection *collection;
1665
1666         collection = BKE_collection_from_index(scene, collection_index);
1667         BKE_collection_new_name_get(collection, name);
1668
1669         RNA_property_string_set(op->ptr, prop, name);
1670         return WM_operator_props_dialog_popup(C, op, 200, 100);
1671       }
1672     }
1673     return move_to_collection_exec(C, op);
1674   }
1675
1676   Collection *master_collection = BKE_collection_master(scene);
1677
1678   /* We need the data to be allocated so it's available during menu drawing.
1679    * Technically we could use wmOperator->customdata. However there is no free callback
1680    * called to an operator that exit with OPERATOR_INTERFACE to launch a menu.
1681    *
1682    * So we are left with a memory that will necessarily leak. It's a small leak though.*/
1683   if (master_collection_menu == NULL) {
1684     master_collection_menu = MEM_callocN(sizeof(MoveToCollectionData),
1685                                          "MoveToCollectionData menu - expected eventual memleak");
1686   }
1687
1688   master_collection_menu->collection = master_collection;
1689   master_collection_menu->ot = op->type;
1690   move_to_collection_menus_create(op, master_collection_menu);
1691
1692   uiPopupMenu *pup;
1693   uiLayout *layout;
1694
1695   /* Build the menus. */
1696   const char *title = CTX_IFACE_(op->type->translation_context, op->type->name);
1697   pup = UI_popup_menu_begin(C, title, ICON_NONE);
1698   layout = UI_popup_menu_layout(pup);
1699
1700   uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
1701
1702   move_to_collection_menu_create(C, layout, master_collection_menu);
1703
1704   UI_popup_menu_end(C, pup);
1705
1706   return OPERATOR_INTERFACE;
1707 }
1708
1709 void OBJECT_OT_move_to_collection(wmOperatorType *ot)
1710 {
1711   PropertyRNA *prop;
1712
1713   /* identifiers */
1714   ot->name = "Move to Collection";
1715   ot->description = "Move objects to a scene collection";
1716   ot->idname = "OBJECT_OT_move_to_collection";
1717
1718   /* api callbacks */
1719   ot->exec = move_to_collection_exec;
1720   ot->invoke = move_to_collection_invoke;
1721   ot->poll = move_to_collection_poll;
1722
1723   /* flags */
1724   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1725
1726   prop = RNA_def_int(ot->srna,
1727                      "collection_index",
1728                      COLLECTION_INVALID_INDEX,
1729                      COLLECTION_INVALID_INDEX,
1730                      INT_MAX,
1731                      "Collection Index",
1732                      "Index of the collection to move to",
1733                      0,
1734                      INT_MAX);
1735   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
1736   prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Move objects to a new collection");
1737   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
1738   prop = RNA_def_string(ot->srna,
1739                         "new_collection_name",
1740                         NULL,
1741                         MAX_NAME,
1742                         "Name",
1743                         "Name of the newly added collection");
1744   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1745   ot->prop = prop;
1746 }
1747
1748 void OBJECT_OT_link_to_collection(wmOperatorType *ot)
1749 {
1750   PropertyRNA *prop;
1751
1752   /* identifiers */
1753   ot->name = "Link to Collection";
1754   ot->description = "Link objects to a collection";
1755   ot->idname = "OBJECT_OT_link_to_collection";
1756
1757   /* api callbacks */
1758   ot->exec = move_to_collection_exec;
1759   ot->invoke = move_to_collection_invoke;
1760   ot->poll = move_to_collection_poll;
1761
1762   /* flags */
1763   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1764
1765   prop = RNA_def_int(ot->srna,
1766                      "collection_index",
1767                      COLLECTION_INVALID_INDEX,
1768                      COLLECTION_INVALID_INDEX,
1769                      INT_MAX,
1770                      "Collection Index",
1771                      "Index of the collection to move to",
1772                      0,
1773                      INT_MAX);
1774   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
1775   prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Move objects to a new collection");
1776   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
1777   prop = RNA_def_string(ot->srna,
1778                         "new_collection_name",
1779                         NULL,
1780                         MAX_NAME,
1781                         "Name",
1782                         "Name of the newly added collection");
1783   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1784 }