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