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