Cycles: Fix debug compilation after tile stealing commit
[blender.git] / source / blender / editors / object / object_collection.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) Blender Foundation
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup edobj
22  */
23
24 #include <string.h>
25
26 #include "BLI_blenlib.h"
27 #include "BLI_utildefines.h"
28
29 #include "DNA_collection_types.h"
30 #include "DNA_object_types.h"
31 #include "DNA_scene_types.h"
32
33 #include "BKE_collection.h"
34 #include "BKE_context.h"
35 #include "BKE_lib_id.h"
36 #include "BKE_main.h"
37 #include "BKE_object.h"
38 #include "BKE_report.h"
39
40 #include "DEG_depsgraph.h"
41 #include "DEG_depsgraph_build.h"
42
43 #include "ED_object.h"
44 #include "ED_screen.h"
45
46 #include "WM_api.h"
47 #include "WM_types.h"
48
49 #include "RNA_access.h"
50 #include "RNA_define.h"
51 #include "RNA_enum_types.h"
52
53 #include "UI_interface_icons.h"
54
55 #include "object_intern.h"
56
57 /********************* 3d view operators ***********************/
58
59 /* can be called with C == NULL */
60 static const EnumPropertyItem *collection_object_active_itemf(bContext *C,
61                                                               PointerRNA *UNUSED(ptr),
62                                                               PropertyRNA *UNUSED(prop),
63                                                               bool *r_free)
64 {
65   Main *bmain = CTX_data_main(C);
66   Scene *scene = CTX_data_scene(C);
67   Object *ob;
68   EnumPropertyItem *item = NULL, item_tmp = {0};
69   int totitem = 0;
70
71   if (C == NULL) {
72     return DummyRNA_NULL_items;
73   }
74
75   ob = ED_object_context(C);
76
77   /* check that the object exists */
78   if (ob) {
79     Collection *collection;
80     int i = 0, count = 0;
81
82     /* if 2 or more collections, add option to add to all collections */
83     collection = NULL;
84     while ((collection = BKE_collection_object_find(bmain, scene, collection, ob))) {
85       count++;
86     }
87
88     if (count >= 2) {
89       item_tmp.identifier = item_tmp.name = "All Collections";
90       item_tmp.value = INT_MAX; /* this will give NULL on lookup */
91       RNA_enum_item_add(&item, &totitem, &item_tmp);
92       RNA_enum_item_add_separator(&item, &totitem);
93     }
94
95     /* add collections */
96     collection = NULL;
97     while ((collection = BKE_collection_object_find(bmain, scene, collection, ob))) {
98       item_tmp.identifier = item_tmp.name = collection->id.name + 2;
99       item_tmp.icon = UI_icon_color_from_collection(collection);
100       item_tmp.value = i;
101       RNA_enum_item_add(&item, &totitem, &item_tmp);
102       i++;
103     }
104   }
105
106   RNA_enum_item_end(&item, &totitem);
107   *r_free = true;
108
109   return item;
110 }
111
112 /* get the collection back from the enum index, quite awkward and UI specific */
113 static Collection *collection_object_active_find_index(Main *bmain,
114                                                        Scene *scene,
115                                                        Object *ob,
116                                                        const int collection_object_index)
117 {
118   Collection *collection = NULL;
119   int i = 0;
120   while ((collection = BKE_collection_object_find(bmain, scene, collection, ob))) {
121     if (i == collection_object_index) {
122       break;
123     }
124     i++;
125   }
126
127   return collection;
128 }
129
130 static int objects_add_active_exec(bContext *C, wmOperator *op)
131 {
132   Object *ob = ED_object_context(C);
133   Main *bmain = CTX_data_main(C);
134   Scene *scene = CTX_data_scene(C);
135   int single_collection_index = RNA_enum_get(op->ptr, "collection");
136   Collection *single_collection = collection_object_active_find_index(
137       bmain, scene, ob, single_collection_index);
138   bool is_cycle = false;
139   bool updated = false;
140
141   if (ob == NULL) {
142     return OPERATOR_CANCELLED;
143   }
144
145   /* now add all selected objects to the collection(s) */
146   FOREACH_COLLECTION_BEGIN (bmain, scene, Collection *, collection) {
147     if (single_collection && collection != single_collection) {
148       continue;
149     }
150     if (!BKE_collection_has_object(collection, ob)) {
151       continue;
152     }
153
154     CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) {
155       if (BKE_collection_has_object(collection, base->object)) {
156         continue;
157       }
158
159       if (!BKE_collection_object_cyclic_check(bmain, base->object, collection)) {
160         BKE_collection_object_add(bmain, collection, base->object);
161         DEG_id_tag_update(&collection->id, ID_RECALC_COPY_ON_WRITE);
162         updated = true;
163       }
164       else {
165         is_cycle = true;
166       }
167     }
168     CTX_DATA_END;
169   }
170   FOREACH_COLLECTION_END;
171
172   if (is_cycle) {
173     BKE_report(op->reports, RPT_WARNING, "Skipped some collections because of cycle detected");
174   }
175
176   if (!updated) {
177     return OPERATOR_CANCELLED;
178   }
179
180   DEG_relations_tag_update(bmain);
181   WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
182
183   return OPERATOR_FINISHED;
184 }
185
186 void COLLECTION_OT_objects_add_active(wmOperatorType *ot)
187 {
188   PropertyRNA *prop;
189
190   /* identifiers */
191   ot->name = "Add Selected to Active Collection";
192   ot->description = "Add the object to an object collection that contains the active object";
193   ot->idname = "COLLECTION_OT_objects_add_active";
194
195   /* api callbacks */
196   ot->exec = objects_add_active_exec;
197   ot->invoke = WM_menu_invoke;
198   ot->poll = ED_operator_objectmode;
199
200   /* flags */
201   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
202
203   /* properties */
204   prop = RNA_def_enum(ot->srna,
205                       "collection",
206                       DummyRNA_NULL_items,
207                       0,
208                       "Collection",
209                       "The collection to add other selected objects to");
210   RNA_def_enum_funcs(prop, collection_object_active_itemf);
211   RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
212   ot->prop = prop;
213 }
214
215 static int objects_remove_active_exec(bContext *C, wmOperator *op)
216 {
217   Main *bmain = CTX_data_main(C);
218   Scene *scene = CTX_data_scene(C);
219   ViewLayer *view_layer = CTX_data_view_layer(C);
220   Object *ob = OBACT(view_layer);
221   int single_collection_index = RNA_enum_get(op->ptr, "collection");
222   Collection *single_collection = collection_object_active_find_index(
223       bmain, scene, ob, single_collection_index);
224   bool ok = false;
225
226   if (ob == NULL) {
227     return OPERATOR_CANCELLED;
228   }
229
230   /* Linking to same collection requires its own loop so we can avoid
231    * looking up the active objects collections each time. */
232   FOREACH_COLLECTION_BEGIN (bmain, scene, Collection *, collection) {
233     if (single_collection && collection != single_collection) {
234       continue;
235     }
236
237     if (BKE_collection_has_object(collection, ob)) {
238       /* Remove collections from selected objects */
239       CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) {
240         BKE_collection_object_remove(bmain, collection, base->object, false);
241         DEG_id_tag_update(&collection->id, ID_RECALC_COPY_ON_WRITE);
242         ok = 1;
243       }
244       CTX_DATA_END;
245     }
246   }
247   FOREACH_COLLECTION_END;
248
249   if (!ok) {
250     BKE_report(op->reports, RPT_ERROR, "Active object contains no collections");
251   }
252
253   DEG_relations_tag_update(bmain);
254   WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
255
256   return OPERATOR_FINISHED;
257 }
258
259 void COLLECTION_OT_objects_remove_active(wmOperatorType *ot)
260 {
261   PropertyRNA *prop;
262
263   /* identifiers */
264   ot->name = "Remove Selected from Active Collection";
265   ot->description = "Remove the object from an object collection that contains the active object";
266   ot->idname = "COLLECTION_OT_objects_remove_active";
267
268   /* api callbacks */
269   ot->exec = objects_remove_active_exec;
270   ot->invoke = WM_menu_invoke;
271   ot->poll = ED_operator_objectmode;
272
273   /* flags */
274   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
275
276   /* properties */
277   prop = RNA_def_enum(ot->srna,
278                       "collection",
279                       DummyRNA_NULL_items,
280                       0,
281                       "Collection",
282                       "The collection to remove other selected objects from");
283   RNA_def_enum_funcs(prop, collection_object_active_itemf);
284   RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
285   ot->prop = prop;
286 }
287
288 static int collection_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op))
289 {
290   Main *bmain = CTX_data_main(C);
291   Scene *scene = CTX_data_scene(C);
292
293   CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) {
294     BKE_object_groups_clear(bmain, scene, base->object);
295   }
296   CTX_DATA_END;
297
298   DEG_relations_tag_update(bmain);
299   WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
300
301   return OPERATOR_FINISHED;
302 }
303
304 void COLLECTION_OT_objects_remove_all(wmOperatorType *ot)
305 {
306   /* identifiers */
307   ot->name = "Remove from All Collections";
308   ot->description = "Remove selected objects from all collections";
309   ot->idname = "COLLECTION_OT_objects_remove_all";
310
311   /* api callbacks */
312   ot->exec = collection_objects_remove_all_exec;
313   ot->poll = ED_operator_objectmode;
314
315   /* flags */
316   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
317 }
318
319 static int collection_objects_remove_exec(bContext *C, wmOperator *op)
320 {
321   Object *ob = ED_object_context(C);
322   Main *bmain = CTX_data_main(C);
323   Scene *scene = CTX_data_scene(C);
324   int single_collection_index = RNA_enum_get(op->ptr, "collection");
325   Collection *single_collection = collection_object_active_find_index(
326       bmain, scene, ob, single_collection_index);
327   bool updated = false;
328
329   if (ob == NULL) {
330     return OPERATOR_CANCELLED;
331   }
332
333   FOREACH_COLLECTION_BEGIN (bmain, scene, Collection *, collection) {
334     if (single_collection && collection != single_collection) {
335       continue;
336     }
337     if (!BKE_collection_has_object(collection, ob)) {
338       continue;
339     }
340
341     /* now remove all selected objects from the collection */
342     CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) {
343       BKE_collection_object_remove(bmain, collection, base->object, false);
344       DEG_id_tag_update(&collection->id, ID_RECALC_COPY_ON_WRITE);
345       updated = true;
346     }
347     CTX_DATA_END;
348   }
349   FOREACH_COLLECTION_END;
350
351   if (!updated) {
352     return OPERATOR_CANCELLED;
353   }
354
355   DEG_relations_tag_update(bmain);
356   WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
357
358   return OPERATOR_FINISHED;
359 }
360
361 void COLLECTION_OT_objects_remove(wmOperatorType *ot)
362 {
363   PropertyRNA *prop;
364
365   /* identifiers */
366   ot->name = "Remove from Collection";
367   ot->description = "Remove selected objects from a collection";
368   ot->idname = "COLLECTION_OT_objects_remove";
369
370   /* api callbacks */
371   ot->exec = collection_objects_remove_exec;
372   ot->invoke = WM_menu_invoke;
373   ot->poll = ED_operator_objectmode;
374
375   /* flags */
376   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
377
378   /* properties */
379   prop = RNA_def_enum(ot->srna,
380                       "collection",
381                       DummyRNA_NULL_items,
382                       0,
383                       "Collection",
384                       "The collection to remove this object from");
385   RNA_def_enum_funcs(prop, collection_object_active_itemf);
386   RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
387   ot->prop = prop;
388 }
389
390 static int collection_create_exec(bContext *C, wmOperator *op)
391 {
392   Main *bmain = CTX_data_main(C);
393   char name[MAX_ID_NAME - 2]; /* id name */
394
395   RNA_string_get(op->ptr, "name", name);
396
397   Collection *collection = BKE_collection_add(bmain, NULL, name);
398   id_fake_user_set(&collection->id);
399
400   CTX_DATA_BEGIN (C, Base *, base, selected_bases) {
401     BKE_collection_object_add(bmain, collection, base->object);
402     DEG_id_tag_update(&collection->id, ID_RECALC_COPY_ON_WRITE);
403   }
404   CTX_DATA_END;
405
406   DEG_relations_tag_update(bmain);
407   WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
408
409   return OPERATOR_FINISHED;
410 }
411
412 void COLLECTION_OT_create(wmOperatorType *ot)
413 {
414   /* identifiers */
415   ot->name = "Create New Collection";
416   ot->description = "Create an object collection from selected objects";
417   ot->idname = "COLLECTION_OT_create";
418
419   /* api callbacks */
420   ot->exec = collection_create_exec;
421   ot->poll = ED_operator_objectmode;
422
423   /* flags */
424   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
425
426   RNA_def_string(
427       ot->srna, "name", "Collection", MAX_ID_NAME - 2, "Name", "Name of the new collection");
428 }
429
430 /****************** properties window operators *********************/
431
432 static int collection_add_exec(bContext *C, wmOperator *UNUSED(op))
433 {
434   Object *ob = ED_object_context(C);
435   Main *bmain = CTX_data_main(C);
436
437   if (ob == NULL) {
438     return OPERATOR_CANCELLED;
439   }
440
441   Collection *collection = BKE_collection_add(bmain, NULL, "Collection");
442   id_fake_user_set(&collection->id);
443   BKE_collection_object_add(bmain, collection, ob);
444
445   DEG_id_tag_update(&collection->id, ID_RECALC_COPY_ON_WRITE);
446   DEG_relations_tag_update(bmain);
447
448   WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
449
450   return OPERATOR_FINISHED;
451 }
452
453 void OBJECT_OT_collection_add(wmOperatorType *ot)
454 {
455   /* identifiers */
456   ot->name = "Add to Collection";
457   ot->idname = "OBJECT_OT_collection_add";
458   ot->description = "Add an object to a new collection";
459
460   /* api callbacks */
461   ot->exec = collection_add_exec;
462   ot->poll = ED_operator_objectmode;
463
464   /* flags */
465   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
466 }
467
468 static int collection_link_exec(bContext *C, wmOperator *op)
469 {
470   Main *bmain = CTX_data_main(C);
471   Object *ob = ED_object_context(C);
472   Collection *collection = BLI_findlink(&bmain->collections, RNA_enum_get(op->ptr, "collection"));
473
474   if (ELEM(NULL, ob, collection)) {
475     return OPERATOR_CANCELLED;
476   }
477
478   /* Early return check, if the object is already in collection
479    * we could skip all the dependency check and just consider
480    * operator is finished.
481    */
482   if (BKE_collection_has_object(collection, ob)) {
483     return OPERATOR_FINISHED;
484   }
485
486   /* Currently this should not be allowed (might be supported in the future though...). */
487   if (ID_IS_OVERRIDE_LIBRARY(&collection->id)) {
488     BKE_report(op->reports, RPT_ERROR, "Could not add the collection because it is overridden");
489     return OPERATOR_CANCELLED;
490   }
491   /* Linked collections are already checked for by using RNA_collection_local_itemf
492    * but operator can be called without invoke */
493   if (ID_IS_LINKED(&collection->id)) {
494     BKE_report(op->reports, RPT_ERROR, "Could not add the collection because it is linked");
495     return OPERATOR_CANCELLED;
496   }
497
498   /* Adding object to collection which is used as dupli-collection for self is bad idea.
499    *
500    * It is also bad idea to add object to collection which is in collection which
501    * contains our current object.
502    */
503   if (BKE_collection_object_cyclic_check(bmain, ob, collection)) {
504     BKE_report(op->reports,
505                RPT_ERROR,
506                "Could not add the collection because of dependency cycle detected");
507     return OPERATOR_CANCELLED;
508   }
509
510   BKE_collection_object_add(bmain, collection, ob);
511
512   DEG_id_tag_update(&collection->id, ID_RECALC_COPY_ON_WRITE);
513   DEG_relations_tag_update(bmain);
514
515   WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
516
517   return OPERATOR_FINISHED;
518 }
519
520 void OBJECT_OT_collection_link(wmOperatorType *ot)
521 {
522   PropertyRNA *prop;
523
524   /* identifiers */
525   ot->name = "Link to Collection";
526   ot->idname = "OBJECT_OT_collection_link";
527   ot->description = "Add an object to an existing collection";
528
529   /* api callbacks */
530   ot->exec = collection_link_exec;
531   ot->invoke = WM_enum_search_invoke;
532   ot->poll = ED_operator_objectmode;
533
534   /* flags */
535   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
536
537   /* properties */
538   prop = RNA_def_enum(ot->srna, "collection", DummyRNA_NULL_items, 0, "Collection", "");
539   RNA_def_enum_funcs(prop, RNA_collection_local_itemf);
540   RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
541   ot->prop = prop;
542 }
543
544 static int collection_remove_exec(bContext *C, wmOperator *UNUSED(op))
545 {
546   Main *bmain = CTX_data_main(C);
547   Object *ob = ED_object_context(C);
548   Collection *collection = CTX_data_pointer_get_type(C, "collection", &RNA_Collection).data;
549
550   if (!ob || !collection) {
551     return OPERATOR_CANCELLED;
552   }
553
554   BKE_collection_object_remove(bmain, collection, ob, false);
555
556   DEG_id_tag_update(&collection->id, ID_RECALC_COPY_ON_WRITE);
557   DEG_relations_tag_update(bmain);
558
559   WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
560
561   return OPERATOR_FINISHED;
562 }
563
564 void OBJECT_OT_collection_remove(wmOperatorType *ot)
565 {
566   /* identifiers */
567   ot->name = "Remove Collection";
568   ot->idname = "OBJECT_OT_collection_remove";
569   ot->description = "Remove the active object from this collection";
570
571   /* api callbacks */
572   ot->exec = collection_remove_exec;
573   ot->poll = ED_operator_objectmode;
574
575   /* flags */
576   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
577 }
578
579 static int collection_unlink_exec(bContext *C, wmOperator *UNUSED(op))
580 {
581   Main *bmain = CTX_data_main(C);
582   Collection *collection = CTX_data_pointer_get_type(C, "collection", &RNA_Collection).data;
583
584   if (!collection) {
585     return OPERATOR_CANCELLED;
586   }
587
588   BKE_id_delete(bmain, collection);
589
590   DEG_relations_tag_update(bmain);
591
592   WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
593
594   return OPERATOR_FINISHED;
595 }
596
597 void OBJECT_OT_collection_unlink(wmOperatorType *ot)
598 {
599   /* identifiers */
600   ot->name = "Unlink Collection";
601   ot->idname = "OBJECT_OT_collection_unlink";
602   ot->description = "Unlink the collection from all objects";
603
604   /* api callbacks */
605   ot->exec = collection_unlink_exec;
606   ot->poll = ED_operator_objectmode;
607
608   /* flags */
609   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
610 }
611
612 /* Select objects in the same collection as the active */
613 static int select_grouped_exec(bContext *C, wmOperator *UNUSED(op))
614 {
615   Scene *scene = CTX_data_scene(C);
616   Collection *collection = CTX_data_pointer_get_type(C, "collection", &RNA_Collection).data;
617
618   if (!collection) {
619     return OPERATOR_CANCELLED;
620   }
621
622   CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
623     if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
624       if (BKE_collection_has_object_recursive(collection, base->object)) {
625         ED_object_base_select(base, BA_SELECT);
626       }
627     }
628   }
629   CTX_DATA_END;
630
631   DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
632   WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
633
634   return OPERATOR_FINISHED;
635 }
636
637 void OBJECT_OT_collection_objects_select(wmOperatorType *ot)
638 {
639   /* identifiers */
640   ot->name = "Select Objects in Collection";
641   ot->idname = "OBJECT_OT_collection_objects_select";
642   ot->description = "Select all objects in collection";
643
644   /* api callbacks */
645   ot->exec = select_grouped_exec;
646   ot->poll = ED_operator_objectmode;
647
648   /* flags */
649   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
650 }