Fixup for rB6cdb3845 (Added collection props getter/setter)
[blender.git] / source / blender / blenkernel / intern / layer.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  * Contributor(s): Dalai Felinto
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/blenkernel/intern/layer.c
24  *  \ingroup bke
25  */
26
27 #include "BLI_listbase.h"
28 #include "BLI_string.h"
29 #include "BLI_string_utf8.h"
30 #include "BLI_string_utils.h"
31 #include "BLT_translation.h"
32
33 #include "BKE_layer.h"
34 #include "BKE_collection.h"
35 #include "BKE_layer.h"
36 #include "BKE_main.h"
37 #include "BKE_node.h"
38
39 #include "DNA_ID.h"
40 #include "DNA_layer_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_node_types.h"
43 #include "DNA_scene_types.h"
44
45 #include "MEM_guardedalloc.h"
46
47 /* prototype */
48 struct CollectionEngineSettingsCB_Type;
49 static void layer_collection_free(SceneLayer *sl, LayerCollection *lc);
50 static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc);
51 static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc);
52 static void collection_engine_settings_create(ListBase *lb, struct CollectionEngineSettingsCB_Type *ces_type);
53 static void layer_collection_create_engine_settings(LayerCollection *lc);
54 static void object_bases_Iterator_next(Iterator *iter, const int flag);
55
56 /* RenderLayer */
57
58 /**
59  * Add a new renderlayer
60  * by default, a renderlayer has the master collection
61  */
62 SceneLayer *BKE_scene_layer_add(Scene *scene, const char *name)
63 {
64         if (!name) {
65                 name = DATA_("Render Layer");
66         }
67
68         SceneLayer *sl = MEM_callocN(sizeof(SceneLayer), "Scene Layer");
69         sl->flag |= SCENE_LAYER_RENDER;
70
71         BLI_addtail(&scene->render_layers, sl);
72
73         /* unique name */
74         BLI_strncpy_utf8(sl->name, name, sizeof(sl->name));
75         BLI_uniquename(&scene->render_layers, sl, DATA_("SceneLayer"), '.', offsetof(SceneLayer, name), sizeof(sl->name));
76
77         SceneCollection *sc = BKE_collection_master(scene);
78         layer_collection_add(sl, &sl->layer_collections, sc);
79
80         return sl;
81 }
82
83 bool BKE_scene_layer_remove(Main *bmain, Scene *scene, SceneLayer *sl)
84 {
85         const int act = BLI_findindex(&scene->render_layers, sl);
86
87         if (act == -1) {
88                 return false;
89         }
90         else if ( (scene->render_layers.first == scene->render_layers.last) &&
91                   (scene->render_layers.first == sl))
92         {
93                 /* ensure 1 layer is kept */
94                 return false;
95         }
96
97         BLI_remlink(&scene->render_layers, sl);
98
99         BKE_scene_layer_free(sl);
100         MEM_freeN(sl);
101
102         scene->active_layer = 0;
103         /* TODO WORKSPACE: set active_layer to 0 */
104
105         for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
106                 if (sce->nodetree) {
107                         BKE_nodetree_remove_layer_n(sce->nodetree, scene, act);
108                 }
109         }
110
111         return true;
112 }
113
114 /**
115  * Free (or release) any data used by this SceneLayer (does not free the SceneLayer itself).
116  */
117 void BKE_scene_layer_free(SceneLayer *sl)
118 {
119         sl->basact = NULL;
120         BLI_freelistN(&sl->object_bases);
121
122         for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
123                 layer_collection_free(NULL, lc);
124         }
125         BLI_freelistN(&sl->layer_collections);
126 }
127
128 /**
129  * Set the render engine of a renderlayer
130  */
131 void BKE_scene_layer_engine_set(SceneLayer *sl, const char *engine)
132 {
133         BLI_strncpy_utf8(sl->engine, engine, sizeof(sl->engine));
134 }
135
136 /**
137  * Tag all the selected objects of a renderlayer
138  */
139 void BKE_scene_layer_selected_objects_tag(SceneLayer *sl, const int tag)
140 {
141         for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
142                 if ((base->flag & BASE_SELECTED) != 0) {
143                         base->object->flag |= tag;
144                 }
145                 else {
146                         base->object->flag &= ~tag;
147                 }
148         }
149 }
150
151 static bool find_scene_collection_in_scene_collections(ListBase *lb, const LayerCollection *lc)
152 {
153         for (LayerCollection *lcn = lb->first; lcn; lcn = lcn->next) {
154                 if (lcn == lc) {
155                         return true;
156                 }
157                 if (find_scene_collection_in_scene_collections(&lcn->layer_collections, lc)) {
158                         return true;
159                 }
160         }
161         return false;
162 }
163
164 /**
165  * Find the SceneLayer a LayerCollection belongs to
166  */
167 SceneLayer *BKE_scene_layer_find_from_collection(Scene *scene, LayerCollection *lc)
168 {
169         for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
170                 if (find_scene_collection_in_scene_collections(&sl->layer_collections, lc)) {
171                         return sl;
172                 }
173         }
174         return false;
175 }
176
177 /* ObjectBase */
178
179 ObjectBase *BKE_scene_layer_base_find(SceneLayer *sl, Object *ob)
180 {
181         return BLI_findptr(&sl->object_bases, ob, offsetof(ObjectBase, object));
182 }
183
184 void BKE_scene_layer_base_deselect_all(SceneLayer *sl)
185 {
186         ObjectBase *base;
187
188         for (base = sl->object_bases.first; base; base = base->next) {
189                 base->flag &= ~BASE_SELECTED;
190         }
191 }
192
193 void BKE_scene_layer_base_select(struct SceneLayer *sl, ObjectBase *selbase)
194 {
195         sl->basact = selbase;
196         if ((selbase->flag & BASE_SELECTABLED) != 0) {
197                 selbase->flag |= BASE_SELECTED;
198         }
199 }
200
201 static void scene_layer_object_base_unref(SceneLayer* sl, ObjectBase *base)
202 {
203         base->refcount--;
204
205         /* It only exists in the RenderLayer */
206         if (base->refcount == 0) {
207                 if (sl->basact == base) {
208                         sl->basact = NULL;
209                 }
210
211                 BLI_remlink(&sl->object_bases, base);
212                 MEM_freeN(base);
213         }
214 }
215
216 static void layer_collection_base_flag_recalculate(LayerCollection *lc, const bool tree_is_visible, const bool tree_is_selectable)
217 {
218         bool is_visible = tree_is_visible && ((lc->flag & COLLECTION_VISIBLE) != 0);
219         /* an object can only be selected if it's visible */
220         bool is_selectable = tree_is_selectable && is_visible && ((lc->flag & COLLECTION_SELECTABLE) != 0);
221
222         for (LinkData *link = lc->object_bases.first; link; link = link->next) {
223                 ObjectBase *base = link->data;
224
225                 if (is_visible) {
226                         base->flag |= BASE_VISIBLED;
227                 }
228                 else {
229                         base->flag &= ~BASE_VISIBLED;
230                 }
231
232                 if (is_selectable) {
233                         base->flag |= BASE_SELECTABLED;
234                 }
235                 else {
236                         base->flag &= ~BASE_SELECTABLED;
237                 }
238         }
239
240         for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) {
241                 layer_collection_base_flag_recalculate(lcn, is_visible, is_selectable);
242         }
243 }
244
245 /**
246  * Re-evaluate the ObjectBase flags for SceneLayer
247  */
248 void BKE_scene_layer_base_flag_recalculate(SceneLayer *sl)
249 {
250         for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
251                 layer_collection_base_flag_recalculate(lc, true, true);
252         }
253
254         /* if base is not selectabled, clear select */
255         for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
256                 if ((base->flag & BASE_SELECTABLED) == 0) {
257                         base->flag &= ~BASE_SELECTED;
258                 }
259         }
260 }
261
262 /**
263  * Return the base if existent, or create it if necessary
264  * Always bump the refcount
265  */
266 static ObjectBase *object_base_add(SceneLayer *sl, Object *ob)
267 {
268         ObjectBase *base;
269         base = BKE_scene_layer_base_find(sl, ob);
270
271         if (base == NULL) {
272                 base = MEM_callocN(sizeof(ObjectBase), "Object Base");
273
274                 /* do not bump user count, leave it for SceneCollections */
275                 base->object = ob;
276                 BLI_addtail(&sl->object_bases, base);
277         }
278         base->refcount++;
279         return base;
280 }
281
282 /* LayerCollection */
283
284 /**
285  * When freeing the entire SceneLayer at once we don't bother with unref
286  * otherwise SceneLayer is passed to keep the syncing of the LayerCollection tree
287  */
288 static void layer_collection_free(SceneLayer *sl, LayerCollection *lc)
289 {
290         if (sl) {
291                 for (LinkData *link = lc->object_bases.first; link; link = link->next) {
292                         scene_layer_object_base_unref(sl, link->data);
293                 }
294         }
295
296         BLI_freelistN(&lc->object_bases);
297         BLI_freelistN(&lc->overrides);
298         BKE_layer_collection_engine_settings_free(&lc->engine_settings);
299
300         for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
301                 layer_collection_free(sl, nlc);
302         }
303
304         BLI_freelistN(&lc->layer_collections);
305 }
306
307 /**
308  * Free (or release) LayerCollection from SceneLayer
309  * (does not free the LayerCollection itself).
310  */
311 void BKE_layer_collection_free(SceneLayer *sl, LayerCollection *lc)
312 {
313         layer_collection_free(sl, lc);
314 }
315
316 /* LayerCollection */
317
318 /**
319  * Recursively get the collection for a given index
320  */
321 static LayerCollection *collection_from_index(ListBase *lb, const int number, int *i)
322 {
323         for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
324                 if (*i == number) {
325                         return lc;
326                 }
327
328                 (*i)++;
329
330                 LayerCollection *lc_nested = collection_from_index(&lc->layer_collections, number, i);
331                 if (lc_nested) {
332                         return lc_nested;
333                 }
334         }
335         return NULL;
336 }
337
338 /**
339  * Get the active collection
340  */
341 LayerCollection *BKE_layer_collection_active(SceneLayer *sl)
342 {
343         int i = 0;
344         return collection_from_index(&sl->layer_collections, sl->active_collection, &i);
345 }
346
347 /**
348  * Recursively get the count of collections
349  */
350 static int collection_count(ListBase *lb)
351 {
352         int i = 0;
353         for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
354                 i += collection_count(&lc->layer_collections) + 1;
355         }
356         return i;
357 }
358
359 /**
360  * Get the total number of collections
361  * (including all the nested collections)
362  */
363 int BKE_layer_collection_count(SceneLayer *sl)
364 {
365         return collection_count(&sl->layer_collections);
366 }
367
368 /**
369  * Recursively get the index for a given collection
370  */
371 static int index_from_collection(ListBase *lb, LayerCollection *lc, int *i)
372 {
373         for (LayerCollection *lcol = lb->first; lcol; lcol = lcol->next) {
374                 if (lcol == lc) {
375                         return *i;
376                 }
377
378                 (*i)++;
379
380                 int i_nested = index_from_collection(&lcol->layer_collections, lc, i);
381                 if (i_nested != -1) {
382                         return i_nested;
383                 }
384         }
385         return -1;
386 }
387
388 /**
389  * Return -1 if not found
390  */
391 int BKE_layer_collection_findindex(SceneLayer *sl, LayerCollection *lc)
392 {
393         int i = 0;
394         return index_from_collection(&sl->layer_collections, lc, &i);
395 }
396
397 /**
398  * Link a collection to a renderlayer
399  * The collection needs to be created separately
400  */
401 LayerCollection *BKE_collection_link(SceneLayer *sl, SceneCollection *sc)
402 {
403         LayerCollection *lc = layer_collection_add(sl, &sl->layer_collections, sc);
404         sl->active_collection = BKE_layer_collection_findindex(sl, lc);
405         return lc;
406 }
407
408 /**
409  * Unlink a collection base from a renderlayer
410  * The corresponding collection is not removed from the master collection
411  */
412 void BKE_collection_unlink(SceneLayer *sl, LayerCollection *lc)
413 {
414         BKE_layer_collection_free(sl, lc);
415         BKE_scene_layer_base_flag_recalculate(sl);
416
417         BLI_remlink(&sl->layer_collections, lc);
418         MEM_freeN(lc);
419         sl->active_collection = 0;
420 }
421
422 static void layer_collection_object_add(SceneLayer *sl, LayerCollection *lc, Object *ob)
423 {
424         ObjectBase *base = object_base_add(sl, ob);
425
426         /* only add an object once - prevent SceneCollection->objects and
427          * SceneCollection->filter_objects to add the same object */
428
429         if (BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data))) {
430                 return;
431         }
432
433         BKE_scene_layer_base_flag_recalculate(sl);
434
435         BLI_addtail(&lc->object_bases, BLI_genericNodeN(base));
436 }
437
438 static void layer_collection_object_remove(SceneLayer *sl, LayerCollection *lc, Object *ob)
439 {
440         ObjectBase *base;
441         base = BKE_scene_layer_base_find(sl, ob);
442
443         LinkData *link = BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data));
444         BLI_remlink(&lc->object_bases, link);
445         MEM_freeN(link);
446
447         scene_layer_object_base_unref(sl, base);
448 }
449
450 static void layer_collection_objects_populate(SceneLayer *sl, LayerCollection *lc, ListBase *objects)
451 {
452         for (LinkData *link = objects->first; link; link = link->next) {
453                 layer_collection_object_add(sl, lc, link->data);
454         }
455 }
456
457 static void layer_collection_populate(SceneLayer *sl, LayerCollection *lc, SceneCollection *sc)
458 {
459         layer_collection_objects_populate(sl, lc, &sc->objects);
460         layer_collection_objects_populate(sl, lc, &sc->filter_objects);
461
462         for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
463                 layer_collection_add(sl, &lc->layer_collections, nsc);
464         }
465 }
466
467 static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc)
468 {
469         LayerCollection *lc = MEM_callocN(sizeof(LayerCollection), "Collection Base");
470         BLI_addtail(lb, lc);
471
472         lc->scene_collection = sc;
473         lc->flag = COLLECTION_VISIBLE + COLLECTION_SELECTABLE + COLLECTION_FOLDED;
474
475         layer_collection_create_engine_settings(lc);
476         layer_collection_populate(sl, lc, sc);
477         return lc;
478 }
479
480
481 /* ---------------------------------------------------------------------- */
482
483 /**
484  * See if render layer has the scene collection linked directly, or indirectly (nested)
485  */
486 bool BKE_scene_layer_has_collection(struct SceneLayer *sl, struct SceneCollection *sc)
487 {
488         for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
489                 if (find_layer_collection_by_scene_collection(lc, sc) != NULL) {
490                         return true;
491                 }
492         }
493         return false;
494 }
495
496 /**
497  * See if the object is in any of the scene layers of the scene
498  */
499 bool BKE_scene_has_object(Scene *scene, Object *ob)
500 {
501         for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
502                 ObjectBase *base = BKE_scene_layer_base_find(sl, ob);
503                 if (base) {
504                         return true;
505                 }
506         }
507         return false;
508 }
509
510
511 /* ---------------------------------------------------------------------- */
512 /* Syncing */
513
514 static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc)
515 {
516         if (lc->scene_collection == sc) {
517                 return lc;
518         }
519
520         for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
521                 LayerCollection *found = find_layer_collection_by_scene_collection(nlc, sc);
522                 if (found) {
523                         return found;
524                 }
525         }
526         return NULL;
527 }
528
529 /**
530  * Add a new LayerCollection for all the SceneLayers that have sc_parent
531  */
532 void BKE_layer_sync_new_scene_collection(Scene *scene, const SceneCollection *sc_parent, SceneCollection *sc)
533 {
534         for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
535                 for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
536                         LayerCollection *lc_parent = find_layer_collection_by_scene_collection(lc, sc_parent);
537                         if (lc_parent) {
538                                 layer_collection_add(sl, &lc_parent->layer_collections, sc);
539                         }
540                 }
541         }
542 }
543
544 /**
545  * Add a corresponding ObjectBase to all the equivalent LayerCollection
546  */
547 void BKE_layer_sync_object_link(Scene *scene, SceneCollection *sc, Object *ob)
548 {
549         for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
550                 for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
551                         LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
552                         if (found) {
553                                 layer_collection_object_add(sl, found, ob);
554                         }
555                 }
556         }
557 }
558
559 /**
560  * Remove the equivalent object base to all layers that have this collection
561  * also remove all reference to ob in the filter_objects
562  */
563 void BKE_layer_sync_object_unlink(Scene *scene, SceneCollection *sc, Object *ob)
564 {
565         for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
566                 for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
567                         LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
568                         if (found) {
569                                 layer_collection_object_remove(sl, found, ob);
570                         }
571                 }
572                 BKE_scene_layer_base_flag_recalculate(sl);
573         }
574 }
575
576 /* ---------------------------------------------------------------------- */
577 /* Override */
578
579 /**
580  * Add a new datablock override
581  */
582 void BKE_collection_override_datablock_add(LayerCollection *UNUSED(lc), const char *UNUSED(data_path), ID *UNUSED(id))
583 {
584         TODO_LAYER_OVERRIDE;
585 }
586
587 /* ---------------------------------------------------------------------- */
588 /* Engine Settings */
589
590 ListBase R_engines_settings_callbacks = {NULL, NULL};
591
592 typedef struct CollectionEngineSettingsCB_Type {
593         struct CollectionEngineSettingsCB_Type *next, *prev;
594
595         char name[MAX_NAME]; /* engine name */
596
597         CollectionEngineSettingsCB callback;
598
599 } CollectionEngineSettingsCB_Type;
600
601 static void create_engine_settings_layer_collection(LayerCollection *lc, CollectionEngineSettingsCB_Type *ces_type)
602 {
603         if (BKE_layer_collection_engine_get(lc, ces_type->name)) {
604                 return;
605         }
606
607         collection_engine_settings_create(&lc->engine_settings, ces_type);
608
609         for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) {
610                 create_engine_settings_layer_collection(lcn, ces_type);
611         }
612 }
613
614 static void create_engines_settings_scene(Scene *scene, CollectionEngineSettingsCB_Type *ces_type)
615 {
616         for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
617                 for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
618                         create_engine_settings_layer_collection(lc, ces_type);
619                 }
620         }
621 }
622
623 void BKE_layer_collection_engine_settings_callback_register(
624         Main *bmain, const char *engine_name, CollectionEngineSettingsCB func)
625 {
626         CollectionEngineSettingsCB_Type *ces_type;
627
628         /* cleanup in case it existed */
629         ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name));
630
631         if (ces_type) {
632                 BLI_remlink(&R_engines_settings_callbacks, ces_type);
633                 MEM_freeN(ces_type);
634         }
635
636         ces_type = MEM_callocN(sizeof(CollectionEngineSettingsCB_Type), "collection_engine_type");
637         BLI_strncpy_utf8(ces_type->name, engine_name, sizeof(ces_type->name));
638         ces_type->callback = func;
639         BLI_addtail(&R_engines_settings_callbacks, ces_type);
640
641         if (bmain) {
642                 /* populate all of the collections of the scene with those settings */
643                 for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
644                         create_engines_settings_scene(scene, ces_type);
645                 }
646         }
647 }
648
649 void BKE_layer_collection_engine_settings_callback_free(void)
650 {
651         BLI_freelistN(&R_engines_settings_callbacks);
652 }
653
654 static void collection_engine_settings_create(ListBase *lb, CollectionEngineSettingsCB_Type *ces_type)
655 {
656         /* create callback data */
657         CollectionEngineSettings *ces = MEM_callocN(sizeof(CollectionEngineSettings), "Collection Engine Settings");
658         BLI_strncpy_utf8(ces->name, ces_type->name, sizeof(ces->name));
659         BLI_addtail(lb, ces);
660
661         /* call callback */
662         ces_type->callback(NULL, ces);
663 }
664
665 /**
666  * Initialize a CollectionEngineSettings
667  *
668  * Usually we would pass LayerCollection->engine_settings
669  * But depsgraph uses this for Object->collection_settings
670  */
671 void BKE_layer_collection_engine_settings_create(ListBase *lb, const char *engine_name)
672 {
673         CollectionEngineSettingsCB_Type *ces_type;
674         ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name));
675         BLI_assert(ces_type);
676         collection_engine_settings_create(lb, ces_type);
677 }
678
679 /**
680  * Free the CollectionEngineSettings ListBase
681  *
682  * Usually we would pass LayerCollection->engine_settings
683  * But depsgraph uses this for Object->collection_settings
684  */
685 void BKE_layer_collection_engine_settings_free(ListBase *lb)
686 {
687         for (CollectionEngineSettings *cse = lb->first; cse; cse = cse->next) {
688                 BLI_freelistN(&cse->properties);
689         }
690         BLI_freelistN(lb);
691 }
692
693 /**
694  * Initialize the render settings for a single LayerCollection
695  */
696 static void layer_collection_create_engine_settings(LayerCollection *lc)
697 {
698         CollectionEngineSettingsCB_Type *ces_type;
699         for (ces_type = R_engines_settings_callbacks.first; ces_type; ces_type = ces_type->next) {
700                 create_engine_settings_layer_collection(lc, ces_type);
701         }
702 }
703
704 /**
705  * Return layer collection engine settings for specified engine
706  */
707 CollectionEngineSettings *BKE_layer_collection_engine_get(LayerCollection *lc, const char *engine_name)
708 {
709         CollectionEngineSettings *ces;
710         ces = BLI_findstring(&lc->engine_settings, engine_name, offsetof(CollectionEngineSettings, name));
711         return ces;
712 }
713
714 /* ---------------------------------------------------------------------- */
715 /* Engine Settings Properties */
716
717 void BKE_collection_engine_property_add_float(CollectionEngineSettings *ces, const char *name, float value)
718 {
719         CollectionEnginePropertyFloat *prop;
720         prop = MEM_callocN(sizeof(CollectionEnginePropertyFloat), "collection engine settings float");
721         prop->data.type = COLLECTION_PROP_TYPE_FLOAT;
722         BLI_strncpy_utf8(prop->data.name, name, sizeof(prop->data.name));
723         prop->value = value;
724         BLI_addtail(&ces->properties, prop);
725 }
726
727 void BKE_collection_engine_property_add_int(CollectionEngineSettings *ces, const char *name, int value)
728 {
729         CollectionEnginePropertyInt *prop;
730         prop = MEM_callocN(sizeof(CollectionEnginePropertyInt), "collection engine settings int");
731         prop->data.type = COLLECTION_PROP_TYPE_INT;
732         BLI_strncpy_utf8(prop->data.name, name, sizeof(prop->data.name));
733         prop->value = value;
734         BLI_addtail(&ces->properties, prop);
735 }
736
737 CollectionEngineProperty *BKE_collection_engine_property_get(CollectionEngineSettings *ces, const char *name)
738 {
739         return BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
740 }
741
742 int BKE_collection_engine_property_value_get_int(CollectionEngineSettings *ces, const char *name)
743 {
744         CollectionEnginePropertyInt *prop;
745         prop = (CollectionEnginePropertyInt *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
746         return prop->value;
747 }
748
749 int BKE_collection_engine_property_value_get_float(CollectionEngineSettings *ces, const char *name)
750 {
751         CollectionEnginePropertyFloat *prop;
752         prop = (CollectionEnginePropertyFloat *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
753         return prop->value;
754 }
755
756 void BKE_collection_engine_property_value_set_int(CollectionEngineSettings *ces, const char *name, int value)
757 {
758         CollectionEnginePropertyInt *prop;
759         prop = (CollectionEnginePropertyInt *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
760         prop->value = value;
761         prop->data.flag |= COLLECTION_PROP_USE;
762 }
763
764 void BKE_collection_engine_property_value_set_float(CollectionEngineSettings *ces, const char *name, float value)
765 {
766         CollectionEnginePropertyFloat *prop;
767         prop = (CollectionEnginePropertyFloat *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
768         prop->value = value;
769         prop->data.flag |= COLLECTION_PROP_USE;
770 }
771
772 /* ---------------------------------------------------------------------- */
773 /* Iterators */
774
775 static void object_bases_Iterator_begin(Iterator *iter, void *data_in, const int flag)
776 {
777         SceneLayer *sl = data_in;
778         ObjectBase *base = sl->object_bases.first;
779
780         /* when there are no objects */
781         if (base ==  NULL) {
782                 iter->valid = false;
783                 return;
784         }
785
786         iter->valid = true;
787         iter->data = base;
788
789         if ((base->flag & flag) == 0) {
790                 object_bases_Iterator_next(iter, flag);
791         }
792         else {
793                 iter->current = base;
794         }
795 }
796
797 static void object_bases_Iterator_next(Iterator *iter, const int flag)
798 {
799         ObjectBase *base = ((ObjectBase *)iter->data)->next;
800
801         while (base) {
802                 if ((base->flag & flag) != 0) {
803                         iter->current = base;
804                         iter->data = base;
805                         return;
806                 }
807                 base = base->next;
808         }
809
810         iter->current = NULL;
811         iter->valid = false;
812 }
813
814 static void objects_Iterator_begin(Iterator *iter, void *data_in, const int flag)
815 {
816         object_bases_Iterator_begin(iter, data_in, flag);
817
818         if (iter->valid) {
819                 iter->current = ((ObjectBase *)iter->current)->object;
820         }
821 }
822
823 static void objects_Iterator_next(Iterator *iter, const int flag)
824 {
825         object_bases_Iterator_next(iter, flag);
826
827         if (iter->valid) {
828                 iter->current = ((ObjectBase *)iter->current)->object;
829         }
830 }
831
832 void BKE_selected_objects_Iterator_begin(Iterator *iter, void *data_in)
833 {
834         objects_Iterator_begin(iter, data_in, BASE_SELECTED);
835 }
836
837 void BKE_selected_objects_Iterator_next(Iterator *iter)
838 {
839         objects_Iterator_next(iter, BASE_SELECTED);
840 }
841
842 void BKE_selected_objects_Iterator_end(Iterator *UNUSED(iter))
843 {
844         /* do nothing */
845 }
846
847 void BKE_visible_objects_Iterator_begin(Iterator *iter, void *data_in)
848 {
849         objects_Iterator_begin(iter, data_in, BASE_VISIBLED);
850 }
851
852 void BKE_visible_objects_Iterator_next(Iterator *iter)
853 {
854         objects_Iterator_next(iter, BASE_VISIBLED);
855 }
856
857 void BKE_visible_objects_Iterator_end(Iterator *UNUSED(iter))
858 {
859         /* do nothing */
860 }
861
862 void BKE_visible_bases_Iterator_begin(Iterator *iter, void *data_in)
863 {
864         object_bases_Iterator_begin(iter, data_in, BASE_VISIBLED);
865 }
866
867 void BKE_visible_bases_Iterator_next(Iterator *iter)
868 {
869         object_bases_Iterator_next(iter, BASE_VISIBLED);
870 }
871
872 void BKE_visible_bases_Iterator_end(Iterator *UNUSED(iter))
873 {
874         /* do nothing */
875 }