Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / 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) 2001-2002 by NaN Holding BV.
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/blenkernel/intern/group.c
29  *  \ingroup bke
30  */
31
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <math.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_group_types.h"
40 #include "DNA_material_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_particle_types.h"
44
45 #include "BLI_blenlib.h"
46 #include "BLI_utildefines.h"
47
48 #include "BKE_global.h"
49 #include "BKE_group.h"
50 #include "BKE_icons.h"
51 #include "BKE_library.h"
52 #include "BKE_main.h"
53 #include "BKE_object.h"
54 #include "BKE_scene.h"
55
56 static void free_group_object(GroupObject *go)
57 {
58         MEM_freeN(go);
59 }
60
61 /** Free (or release) any data used by this group (does not free the group itself). */
62 void BKE_group_free(Group *group)
63 {
64         /* don't free group itself */
65         GroupObject *go;
66
67         /* No animdata here. */
68
69         while ((go = BLI_pophead(&group->gobject))) {
70                 free_group_object(go);
71         }
72
73         BKE_previewimg_free(&group->preview);
74 }
75
76 Group *BKE_group_add(Main *bmain, const char *name)
77 {
78         Group *group;
79         
80         group = BKE_libblock_alloc(bmain, ID_GR, name, 0);
81         id_us_min(&group->id);
82         id_us_ensure_real(&group->id);
83         group->layer = (1 << 20) - 1;
84
85         group->preview = NULL;
86
87         return group;
88 }
89
90 /**
91  * Only copy internal data of Group ID from source to already allocated/initialized destination.
92  * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
93  *
94  * WARNING! This function will not handle ID user count!
95  *
96  * \param flag  Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
97  */
98 void BKE_group_copy_data(Main *UNUSED(bmain), Group *group_dst, const Group *group_src, const int flag)
99 {
100         BLI_duplicatelist(&group_dst->gobject, &group_src->gobject);
101
102         /* Do not copy group's preview (same behavior as for objects). */
103         if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0 && false) {  /* XXX TODO temp hack */
104                 BKE_previewimg_id_copy(&group_dst->id, &group_src->id);
105         }
106         else {
107                 group_dst->preview = NULL;
108         }
109 }
110
111 Group *BKE_group_copy(Main *bmain, const Group *group)
112 {
113         Group *group_copy;
114         BKE_id_copy_ex(bmain, &group->id, (ID **)&group_copy, 0, false);
115         return group_copy;
116 }
117
118 void BKE_group_make_local(Main *bmain, Group *group, const bool lib_local)
119 {
120         BKE_id_make_local_generic(bmain, &group->id, true, lib_local);
121 }
122
123 /* external */
124 static bool group_object_add_internal(Group *group, Object *ob)
125 {
126         GroupObject *go;
127         
128         if (group == NULL || ob == NULL) {
129                 return false;
130         }
131         
132         /* check if the object has been added already */
133         if (BLI_findptr(&group->gobject, ob, offsetof(GroupObject, ob))) {
134                 return false;
135         }
136         
137         go = MEM_callocN(sizeof(GroupObject), "groupobject");
138         BLI_addtail(&group->gobject, go);
139         
140         go->ob = ob;
141         id_us_ensure_real(&go->ob->id);
142         
143         return true;
144 }
145
146 bool BKE_group_object_add(Group *group, Object *object)
147 {
148         if (group_object_add_internal(group, object)) {
149                 if ((object->flag & OB_FROMGROUP) == 0) {
150                         object->flag |= OB_FROMGROUP;
151                 }
152                 return true;
153         }
154         else {
155                 return false;
156         }
157 }
158
159 /* also used for (ob == NULL) */
160 static int group_object_unlink_internal(Group *group, Object *ob)
161 {
162         GroupObject *go, *gon;
163         int removed = 0;
164         if (group == NULL) return 0;
165         
166         go = group->gobject.first;
167         while (go) {
168                 gon = go->next;
169                 if (go->ob == ob) {
170                         BLI_remlink(&group->gobject, go);
171                         free_group_object(go);
172                         removed = 1;
173                         /* should break here since an object being in a group twice cant happen? */
174                 }
175                 go = gon;
176         }
177         return removed;
178 }
179
180 static bool group_object_cyclic_check_internal(Object *object, Group *group)
181 {
182         if (object->dup_group) {
183                 Group *dup_group = object->dup_group;
184                 if ((dup_group->id.tag & LIB_TAG_DOIT) == 0) {
185                         /* Cycle already exists in groups, let's prevent further crappyness */
186                         return true;
187                 }
188                 /* flag the object to identify cyclic dependencies in further dupli groups */
189                 dup_group->id.tag &= ~LIB_TAG_DOIT;
190
191                 if (dup_group == group)
192                         return true;
193                 else {
194                         GroupObject *gob;
195                         for (gob = dup_group->gobject.first; gob; gob = gob->next) {
196                                 if (group_object_cyclic_check_internal(gob->ob, group)) {
197                                         return true;
198                                 }
199                         }
200                 }
201
202                 /* un-flag the object, it's allowed to have the same group multiple times in parallel */
203                 dup_group->id.tag |= LIB_TAG_DOIT;
204         }
205
206         return false;
207 }
208
209 bool BKE_group_object_cyclic_check(Main *bmain, Object *object, Group *group)
210 {
211         /* first flag all groups */
212         BKE_main_id_tag_listbase(&bmain->group, LIB_TAG_DOIT, true);
213
214         return group_object_cyclic_check_internal(object, group);
215 }
216
217 bool BKE_group_object_unlink(Group *group, Object *object)
218 {
219         if (group_object_unlink_internal(group, object)) {
220                 /* object can be NULL */
221                 if (object && BKE_group_object_find(NULL, object) == NULL) {
222                         object->flag &= ~OB_FROMGROUP;
223                 }
224                 return true;
225         }
226         else {
227                 return false;
228         }
229 }
230
231 bool BKE_group_object_exists(Group *group, Object *ob)
232 {
233         if (group == NULL || ob == NULL) {
234                 return false;
235         }
236         else {
237                 return (BLI_findptr(&group->gobject, ob, offsetof(GroupObject, ob)) != NULL);
238         }
239 }
240
241 Group *BKE_group_object_find(Group *group, Object *ob)
242 {
243         if (group)
244                 group = group->id.next;
245         else
246                 group = G.main->group.first;
247         
248         while (group) {
249                 if (BKE_group_object_exists(group, ob))
250                         return group;
251                 group = group->id.next;
252         }
253         return NULL;
254 }
255
256 bool BKE_group_is_animated(Group *group, Object *UNUSED(parent))
257 {
258         GroupObject *go;
259
260 #if 0 /* XXX OLD ANIMSYS, NLASTRIPS ARE NO LONGER USED */
261         if (parent->nlastrips.first)
262                 return 1;
263 #endif
264
265         for (go = group->gobject.first; go; go = go->next)
266                 if (go->ob && go->ob->proxy)
267                         return true;
268
269         return false;
270 }
271
272 #if 0 // add back when timeoffset & animsys work again
273 /* only replaces object strips or action when parent nla instructs it */
274 /* keep checking nla.c though, in case internal structure of strip changes */
275 static void group_replaces_nla(Object *parent, Object *target, char mode)
276 {
277         static ListBase nlastrips = {NULL, NULL};
278         static bAction *action = NULL;
279         static bool done = false;
280         bActionStrip *strip, *nstrip;
281         
282         if (mode == 's') {
283                 
284                 for (strip = parent->nlastrips.first; strip; strip = strip->next) {
285                         if (strip->object == target) {
286                                 if (done == 0) {
287                                         /* clear nla & action from object */
288                                         nlastrips = target->nlastrips;
289                                         BLI_listbase_clear(&target->nlastrips);
290                                         action = target->action;
291                                         target->action = NULL;
292                                         target->nlaflag |= OB_NLA_OVERRIDE;
293                                         done = true;
294                                 }
295                                 nstrip = MEM_dupallocN(strip);
296                                 BLI_addtail(&target->nlastrips, nstrip);
297                         }
298                 }
299         }
300         else if (mode == 'e') {
301                 if (done) {
302                         BLI_freelistN(&target->nlastrips);
303                         target->nlastrips = nlastrips;
304                         target->action = action;
305                         
306                         BLI_listbase_clear(&nlastrips);  /* not needed, but yah... :) */
307                         action = NULL;
308                         done = false;
309                 }
310         }
311 }
312 #endif
313
314 /* puts all group members in local timing system, after this call
315  * you can draw everything, leaves tags in objects to signal it needs further updating */
316
317 /* note: does not work for derivedmesh and render... it recreates all again in convertblender.c */
318 void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx, Scene *scene, Object *UNUSED(parent), Group *group)
319 {
320         GroupObject *go;
321         
322 #if 0 /* warning, isn't clearing the recalc flag on the object which causes it to run all the time,
323            * not just on frame change.
324            * This isn't working because the animation data is only re-evaluated on frame change so commenting for now
325            * but when its enabled at some point it will need to be changed so as not to update so much - campbell */
326
327         /* if animated group... */
328         if (parent->nlastrips.first) {
329                 int cfrao;
330                 
331                 /* switch to local time */
332                 cfrao = scene->r.cfra;
333                 
334                 /* we need a DAG per group... */
335                 for (go = group->gobject.first; go; go = go->next) {
336                         if (go->ob && go->recalc) {
337                                 go->ob->recalc = go->recalc;
338                                 
339                                 group_replaces_nla(parent, go->ob, 's');
340                                 BKE_object_handle_update(eval_ctx, scene, go->ob);
341                                 group_replaces_nla(parent, go->ob, 'e');
342                                 
343                                 /* leave recalc tags in case group members are in normal scene */
344                                 go->ob->recalc = go->recalc;
345                         }
346                 }
347                 
348                 /* restore */
349                 scene->r.cfra = cfrao;
350         }
351         else
352 #endif
353         {
354                 /* only do existing tags, as set by regular depsgraph */
355                 for (go = group->gobject.first; go; go = go->next) {
356                         if (go->ob) {
357                                 if (go->ob->recalc) {
358                                         BKE_object_handle_update(eval_ctx, scene, go->ob);
359                                 }
360                         }
361                 }
362         }
363 }