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