Welcome to mirror list, hosted at ThFree Co, Russian Federation.

BKE_collection.h « blenkernel « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4346c2a3d236d82174ad932028b4c01007754f5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
/* SPDX-License-Identifier: GPL-2.0-or-later */

#pragma once

/** \file
 * \ingroup bke
 */

#include "BLI_compiler_compat.h"
#include "BLI_ghash.h"
#include "BLI_iterator.h"
#include "BLI_sys_types.h"

#include "DNA_listBase.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Structs */

struct BLI_Iterator;
struct Base;
struct BlendDataReader;
struct BlendExpander;
struct BlendLibReader;
struct BlendWriter;
struct Collection;
struct ID;
struct Library;
struct Main;
struct Object;
struct Scene;
struct SceneCollection;
struct ViewLayer;

typedef struct CollectionParent {
  struct CollectionParent *next, *prev;
  struct Collection *collection;
} CollectionParent;

/* Collections */

/**
 * Add a collection to a collection ListBase and synchronize all render layers
 * The ListBase is NULL when the collection is to be added to the master collection
 */
struct Collection *BKE_collection_add(struct Main *bmain,
                                      struct Collection *parent,
                                      const char *name);
/**
 * Add \a collection_dst to all scene collections that reference object \a ob_src is in.
 * Used to replace an instance object with a collection (library override operator).
 *
 * Logic is very similar to #BKE_collection_object_add_from().
 */
void BKE_collection_add_from_object(struct Main *bmain,
                                    struct Scene *scene,
                                    const struct Object *ob_src,
                                    struct Collection *collection_dst);
/**
 * Add \a collection_dst to all scene collections that reference collection \a collection_src is
 * in.
 *
 * Logic is very similar to #BKE_collection_object_add_from().
 */
void BKE_collection_add_from_collection(struct Main *bmain,
                                        struct Scene *scene,
                                        struct Collection *collection_src,
                                        struct Collection *collection_dst);
/**
 * Free (or release) any data used by this collection (does not free the collection itself).
 */
void BKE_collection_free_data(struct Collection *collection);
/**
 * Remove a collection, optionally removing its child objects or moving
 * them to parent collections.
 */
bool BKE_collection_delete(struct Main *bmain, struct Collection *collection, bool hierarchy);

/**
 * Make a deep copy (aka duplicate) of the given collection and all of its children, recursively.
 *
 * \warning This functions will clear all \a bmain #ID.idnew pointers, unless \a
 * #LIB_ID_DUPLICATE_IS_SUBPROCESS duplicate option is passed on, in which case caller is
 * responsible to reconstruct collection dependencies information's
 * (i.e. call #BKE_main_collection_sync).
 */
struct Collection *BKE_collection_duplicate(struct Main *bmain,
                                            struct Collection *parent,
                                            struct Collection *collection,
                                            uint duplicate_flags,
                                            uint duplicate_options);

/* Master Collection for Scene */

#define BKE_SCENE_COLLECTION_NAME "Scene Collection"
struct Collection *BKE_collection_master_add(struct Scene *scene);

/* Collection Objects */

bool BKE_collection_has_object(struct Collection *collection, const struct Object *ob);
bool BKE_collection_has_object_recursive(struct Collection *collection, struct Object *ob);
bool BKE_collection_has_object_recursive_instanced(struct Collection *collection,
                                                   struct Object *ob);
struct Collection *BKE_collection_object_find(struct Main *bmain,
                                              struct Scene *scene,
                                              struct Collection *collection,
                                              struct Object *ob);
bool BKE_collection_is_empty(const struct Collection *collection);

/**
 * Add object to given collection, ensuring this collection is 'editable' (i.e. local and not a
 * liboverride), and finding a suitable parent one otherwise.
 */
bool BKE_collection_object_add(struct Main *bmain,
                               struct Collection *collection,
                               struct Object *ob);

/**
 * Add object to given collection, similar to #BKE_collection_object_add.
 *
 * However, it additionally ensures that the selected collection is also part of the given
 * `view_layer`, if non-NULL. Otherwise, the object is not added to any collection.
 */
bool BKE_collection_viewlayer_object_add(struct Main *bmain,
                                         const struct ViewLayer *view_layer,
                                         struct Collection *collection,
                                         struct Object *ob);

/**
 * Same as #BKE_collection_object_add, but unconditionally adds the object to the given collection.
 *
 * NOTE: required in certain cases, like do-versioning or complex ID management tasks.
 */
bool BKE_collection_object_add_notest(struct Main *bmain,
                                      struct Collection *collection,
                                      struct Object *ob);
/**
 * Add \a ob_dst to all scene collections that reference object \a ob_src is in.
 * Used for copying objects.
 *
 * Logic is very similar to #BKE_collection_add_from_object()
 */
void BKE_collection_object_add_from(struct Main *bmain,
                                    struct Scene *scene,
                                    struct Object *ob_src,
                                    struct Object *ob_dst);
/**
 * Remove object from collection.
 */
bool BKE_collection_object_remove(struct Main *bmain,
                                  struct Collection *collection,
                                  struct Object *object,
                                  bool free_us);
/**
 * Move object from a collection into another
 *
 * If source collection is NULL move it from all the existing collections.
 */
void BKE_collection_object_move(struct Main *bmain,
                                struct Scene *scene,
                                struct Collection *collection_dst,
                                struct Collection *collection_src,
                                struct Object *ob);

/**
 * Remove object from all collections of scene
 */
bool BKE_scene_collections_object_remove(struct Main *bmain,
                                         struct Scene *scene,
                                         struct Object *object,
                                         bool free_us);

/**
 * Check all collections in \a bmain (including embedded ones in scenes) for CollectionObject with
 * NULL object pointer, and remove them.
 */
void BKE_collections_object_remove_nulls(struct Main *bmain);

/**
 * Check all collections in \a bmain (including embedded ones in scenes) for duplicate
 * CollectionObject with a same object pointer within a same object, and remove them.
 *
 * NOTE: Always keeps the first of the detected duplicates.
 */
void BKE_collections_object_remove_duplicates(struct Main *bmain);

/**
 * Remove all NULL children from parent collections of changed \a collection.
 * This is used for library remapping, where these pointers have been set to NULL.
 * Otherwise this should never happen.
 *
 * \note caller must ensure #BKE_main_collection_sync_remap() is called afterwards!
 *
 * \param parent_collection: The collection owning the pointers that were remapped. May be \a NULL,
 * in which case whole \a bmain database of collections is checked.
 * \param child_collection: The collection that was remapped to another pointer. May be \a NULL,
 * in which case whole \a bmain database of collections is checked.
 */
void BKE_collections_child_remove_nulls(struct Main *bmain,
                                        struct Collection *parent_collection,
                                        struct Collection *child_collection);

/* Dependencies. */

bool BKE_collection_is_in_scene(struct Collection *collection);
void BKE_collections_after_lib_link(struct Main *bmain);
bool BKE_collection_object_cyclic_check(struct Main *bmain,
                                        struct Object *object,
                                        struct Collection *collection);

/* Object list cache. */

struct ListBase BKE_collection_object_cache_get(struct Collection *collection);
ListBase BKE_collection_object_cache_instanced_get(struct Collection *collection);
void BKE_collection_object_cache_free(struct Collection *collection);

struct Base *BKE_collection_or_layer_objects(const struct ViewLayer *view_layer,
                                             struct Collection *collection);

/* Editing. */

/**
 * Return Scene Collection for a given index.
 *
 * The index is calculated from top to bottom counting the children before the siblings.
 */
struct Collection *BKE_collection_from_index(struct Scene *scene, int index);
/**
 * The automatic/fallback name of a new collection.
 */
void BKE_collection_new_name_get(struct Collection *collection_parent, char *rname);
/**
 * The name to show in the interface.
 */
const char *BKE_collection_ui_name_get(struct Collection *collection);
/**
 * Select all the objects in this Collection (and its nested collections) for this ViewLayer.
 * Return true if any object was selected.
 */
bool BKE_collection_objects_select(struct ViewLayer *view_layer,
                                   struct Collection *collection,
                                   bool deselect);

/* Collection children */

bool BKE_collection_child_add(struct Main *bmain,
                              struct Collection *parent,
                              struct Collection *child);

bool BKE_collection_child_add_no_sync(struct Collection *parent, struct Collection *child);

bool BKE_collection_child_remove(struct Main *bmain,
                                 struct Collection *parent,
                                 struct Collection *child);

bool BKE_collection_move(struct Main *bmain,
                         struct Collection *to_parent,
                         struct Collection *from_parent,
                         struct Collection *relative,
                         bool relative_after,
                         struct Collection *collection);

/**
 * Find potential cycles in collections.
 *
 * \param new_ancestor: the potential new owner of given \a collection,
 * or the collection to check if the later is NULL.
 * \param collection: the collection we want to add to \a new_ancestor,
 * may be NULL if we just want to ensure \a new_ancestor does not already have cycles.
 * \return true if a cycle is found.
 */
bool BKE_collection_cycle_find(struct Collection *new_ancestor, struct Collection *collection);
/**
 * Find and fix potential cycles in collections.
 *
 * \param collection: The collection to check for existing cycles.
 * \return true if cycles are found and fixed.
 */
bool BKE_collection_cycles_fix(struct Main *bmain, struct Collection *collection);

bool BKE_collection_has_collection(const struct Collection *parent,
                                   const struct Collection *collection);

/**
 * Rebuild parent relationships from child ones, for all children of given \a collection.
 *
 * \note Given collection is assumed to already have valid parents.
 */
void BKE_collection_parent_relations_rebuild(struct Collection *collection);
/**
 * Rebuild parent relationships from child ones, for all collections in given \a bmain.
 */
void BKE_main_collections_parent_relations_rebuild(struct Main *bmain);

/* .blend file I/O */

void BKE_collection_blend_write_nolib(struct BlendWriter *writer, struct Collection *collection);
void BKE_collection_blend_read_data(struct BlendDataReader *reader,
                                    struct Collection *collection,
                                    struct ID *owner_id);
void BKE_collection_blend_read_lib(struct BlendLibReader *reader, struct Collection *collection);
void BKE_collection_blend_read_expand(struct BlendExpander *expander,
                                      struct Collection *collection);

void BKE_collection_compat_blend_read_data(struct BlendDataReader *reader,
                                           struct SceneCollection *sc);
void BKE_collection_compat_blend_read_lib(struct BlendLibReader *reader,
                                          struct Library *lib,
                                          struct SceneCollection *sc);
void BKE_collection_compat_blend_read_expand(struct BlendExpander *expander,
                                             struct SceneCollection *sc);

/* Iteration callbacks. */

typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
typedef void (*BKE_scene_collections_Cb)(struct Collection *ob, void *data);

/* Iteration over objects in collection. */

#define FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN(_collection, _object, _mode) \
  { \
    int _base_flag = (_mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT : BASE_ENABLED_RENDER; \
    int _object_visibility_flag = (_mode == DAG_EVAL_VIEWPORT) ? OB_HIDE_VIEWPORT : \
                                                                 OB_HIDE_RENDER; \
    int _base_id = 0; \
    for (Base *_base = (Base *)BKE_collection_object_cache_get(_collection).first; _base; \
         _base = _base->next, _base_id++) { \
      Object *_object = _base->object; \
      if ((_base->flag & _base_flag) && \
          (_object->visibility_flag & _object_visibility_flag) == 0) {

#define FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END \
  } \
  } \
  } \
  ((void)0)

#define FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(_collection, _object) \
  for (Base *_base = (Base *)BKE_collection_object_cache_get(_collection).first; _base; \
       _base = _base->next) { \
    Object *_object = _base->object; \
    BLI_assert(_object != NULL);

#define FOREACH_COLLECTION_OBJECT_RECURSIVE_END \
  } \
  ((void)0)

/* Iteration over collections in scene. */

/**
 * Only use this in non-performance critical situations
 * (it iterates over all scene collections twice)
 */
void BKE_scene_collections_iterator_begin(struct BLI_Iterator *iter, void *data_in);
void BKE_scene_collections_iterator_next(struct BLI_Iterator *iter);
void BKE_scene_collections_iterator_end(struct BLI_Iterator *iter);

void BKE_scene_objects_iterator_begin(struct BLI_Iterator *iter, void *data_in);
void BKE_scene_objects_iterator_next(struct BLI_Iterator *iter);
void BKE_scene_objects_iterator_end(struct BLI_Iterator *iter);

/** Iterate over objects in the scene based on a flag.
 *
 * \note The object->flag is tested against flag.
 * */
typedef struct SceneObjectsIteratorExData {
  struct Scene *scene;
  int flag;
  void *iter_data;
} SceneObjectsIteratorExData;

void BKE_scene_objects_iterator_begin_ex(struct BLI_Iterator *iter, void *data_in);
void BKE_scene_objects_iterator_next_ex(struct BLI_Iterator *iter);
void BKE_scene_objects_iterator_end_ex(struct BLI_Iterator *iter);

/**
 * Generate a new #GSet (or extend given `objects_gset` if not NULL) with all objects referenced by
 * all collections of given `scene`.
 *
 * \note This will include objects without a base currently
 * (because they would belong to excluded collections only e.g.).
 */
struct GSet *BKE_scene_objects_as_gset(struct Scene *scene, struct GSet *objects_gset);

#define FOREACH_SCENE_COLLECTION_BEGIN(scene, _instance) \
  ITER_BEGIN (BKE_scene_collections_iterator_begin, \
              BKE_scene_collections_iterator_next, \
              BKE_scene_collections_iterator_end, \
              scene, \
              Collection *, \
              _instance)

#define FOREACH_SCENE_COLLECTION_END ITER_END

#define FOREACH_COLLECTION_BEGIN(_bmain, _scene, Type, _instance) \
  { \
    Type _instance; \
    Collection *_instance_next; \
    bool is_scene_collection = (_scene) != NULL; \
\
    if (_scene) { \
      _instance_next = _scene->master_collection; \
    } \
    else { \
      _instance_next = (_bmain)->collections.first; \
    } \
\
    while ((_instance = _instance_next)) { \
      if (is_scene_collection) { \
        _instance_next = (_bmain)->collections.first; \
        is_scene_collection = false; \
      } \
      else { \
        _instance_next = _instance->id.next; \
      }

#define FOREACH_COLLECTION_END \
  } \
  } \
  ((void)0)

#define FOREACH_SCENE_OBJECT_BEGIN(scene, _instance) \
  ITER_BEGIN (BKE_scene_objects_iterator_begin, \
              BKE_scene_objects_iterator_next, \
              BKE_scene_objects_iterator_end, \
              scene, \
              Object *, \
              _instance)

#define FOREACH_SCENE_OBJECT_END ITER_END

#ifdef __cplusplus
}
#endif