Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/collection.c
| Show First 20 Lines • Show All 2,009 Lines • ▼ Show 20 Lines | static void scene_collections_array(Scene *scene, | ||||
| if (scene == NULL) { | if (scene == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| Collection *collection = scene->master_collection; | Collection *collection = scene->master_collection; | ||||
| BLI_assert(collection != NULL); | BLI_assert(collection != NULL); | ||||
| scene_collection_callback(collection, scene_collections_count, r_collections_array_len); | scene_collection_callback(collection, scene_collections_count, r_collections_array_len); | ||||
| if (*r_collections_array_len == 0) { | BLI_assert(*r_collections_array_len > 0); | ||||
| return; | |||||
| } | |||||
| Collection **array = MEM_mallocN(sizeof(Collection *) * (*r_collections_array_len), | Collection **array = MEM_malloc_arrayN( | ||||
| "CollectionArray"); | *r_collections_array_len, sizeof(Collection *), "CollectionArray"); | ||||
| *r_collections_array = array; | *r_collections_array = array; | ||||
| scene_collection_callback(collection, scene_collections_build_array, &array); | scene_collection_callback(collection, scene_collections_build_array, &array); | ||||
| } | } | ||||
| /** | /** | ||||
| * Only use this in non-performance critical situations | * Only use this in non-performance critical situations | ||||
| * (it iterates over all scene collections twice) | * (it iterates over all scene collections twice) | ||||
| */ | */ | ||||
| void BKE_scene_collections_iterator_begin(BLI_Iterator *iter, void *data_in) | void BKE_scene_collections_iterator_begin(BLI_Iterator *iter, void *data_in) | ||||
| { | { | ||||
| Scene *scene = data_in; | Scene *scene = data_in; | ||||
| CollectionsIteratorData *data = MEM_callocN(sizeof(CollectionsIteratorData), __func__); | CollectionsIteratorData *data = MEM_callocN(sizeof(CollectionsIteratorData), __func__); | ||||
| data->scene = scene; | data->scene = scene; | ||||
| BLI_ITERATOR_INIT(iter); | |||||
| iter->data = data; | iter->data = data; | ||||
| iter->valid = true; | |||||
| scene_collections_array(scene, (Collection ***)&data->array, &data->tot); | scene_collections_array(scene, (Collection ***)&data->array, &data->tot); | ||||
| BLI_assert(data->tot != 0); | BLI_assert(data->tot != 0); | ||||
| data->cur = 0; | data->cur = 0; | ||||
| iter->current = data->array[data->cur]; | iter->current = data->array[data->cur]; | ||||
| } | } | ||||
| Show All 25 Lines | |||||
| /* scene objects iterator */ | /* scene objects iterator */ | ||||
| typedef struct SceneObjectsIteratorData { | typedef struct SceneObjectsIteratorData { | ||||
| GSet *visited; | GSet *visited; | ||||
| CollectionObject *cob_next; | CollectionObject *cob_next; | ||||
| BLI_Iterator scene_collection_iter; | BLI_Iterator scene_collection_iter; | ||||
| } SceneObjectsIteratorData; | } SceneObjectsIteratorData; | ||||
| void BKE_scene_objects_iterator_begin(BLI_Iterator *iter, void *data_in) | static void scene_objects_iterator_begin(BLI_Iterator *iter, Scene *scene, GSet *visited_objects) | ||||
| { | { | ||||
| Scene *scene = data_in; | |||||
| SceneObjectsIteratorData *data = MEM_callocN(sizeof(SceneObjectsIteratorData), __func__); | SceneObjectsIteratorData *data = MEM_callocN(sizeof(SceneObjectsIteratorData), __func__); | ||||
| BLI_ITERATOR_INIT(iter); | |||||
| iter->data = data; | iter->data = data; | ||||
| /* lookup list ot make sure each object is object called once */ | /* Lookup list to make sure that each object is only processed once. */ | ||||
| if (visited_objects != NULL) { | |||||
| data->visited = visited_objects; | |||||
| } | |||||
| else { | |||||
| data->visited = BLI_gset_ptr_new(__func__); | data->visited = BLI_gset_ptr_new(__func__); | ||||
| } | |||||
| /* we wrap the scenecollection iterator here to go over the scene collections */ | /* We wrap the scenecollection iterator here to go over the scene collections. */ | ||||
| BKE_scene_collections_iterator_begin(&data->scene_collection_iter, scene); | BKE_scene_collections_iterator_begin(&data->scene_collection_iter, scene); | ||||
| Collection *collection = data->scene_collection_iter.current; | Collection *collection = data->scene_collection_iter.current; | ||||
| data->cob_next = collection->gobject.first; | data->cob_next = collection->gobject.first; | ||||
| BKE_scene_objects_iterator_next(iter); | BKE_scene_objects_iterator_next(iter); | ||||
| } | } | ||||
| void BKE_scene_objects_iterator_begin(BLI_Iterator *iter, void *data_in) | |||||
| { | |||||
| Scene *scene = data_in; | |||||
| scene_objects_iterator_begin(iter, scene, NULL); | |||||
| } | |||||
| /** | /** | ||||
| * Ensures we only get each object once, even when included in several collections. | * Ensures we only get each object once, even when included in several collections. | ||||
| */ | */ | ||||
| static CollectionObject *object_base_unique(GSet *gs, CollectionObject *cob) | static CollectionObject *object_base_unique(GSet *gs, CollectionObject *cob) | ||||
| { | { | ||||
| for (; cob != NULL; cob = cob->next) { | for (; cob != NULL; cob = cob->next) { | ||||
| Object *ob = cob->ob; | Object *ob = cob->ob; | ||||
| void **ob_key_p; | void **ob_key_p; | ||||
| Show All 37 Lines | void BKE_scene_objects_iterator_next(BLI_Iterator *iter) | ||||
| } | } | ||||
| } | } | ||||
| void BKE_scene_objects_iterator_end(BLI_Iterator *iter) | void BKE_scene_objects_iterator_end(BLI_Iterator *iter) | ||||
| { | { | ||||
| SceneObjectsIteratorData *data = iter->data; | SceneObjectsIteratorData *data = iter->data; | ||||
| if (data) { | if (data) { | ||||
| BKE_scene_collections_iterator_end(&data->scene_collection_iter); | BKE_scene_collections_iterator_end(&data->scene_collection_iter); | ||||
| if (data->visited != NULL) { | |||||
| BLI_gset_free(data->visited, NULL); | BLI_gset_free(data->visited, NULL); | ||||
| } | |||||
| MEM_freeN(data); | MEM_freeN(data); | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 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.). | |||||
| */ | |||||
| GSet *BKE_scene_objects_as_gset(Scene *scene, GSet *objects_gset) | |||||
| { | |||||
| BLI_Iterator iter; | |||||
| scene_objects_iterator_begin(&iter, scene, objects_gset); | |||||
| while (iter.valid) { | |||||
| BKE_scene_objects_iterator_next(&iter); | |||||
| } | |||||
| /* `return_gset` is either given `objects_gset` (if non-NULL), or the GSet allocated by the | |||||
| * iterator. Either way, we want to get it back, and prevent `BKE_scene_objects_iterator_end` | |||||
| * from freeing it. */ | |||||
| GSet *return_gset = ((SceneObjectsIteratorData *)iter.data)->visited; | |||||
| ((SceneObjectsIteratorData *)iter.data)->visited = NULL; | |||||
| BKE_scene_objects_iterator_end(&iter); | |||||
| return return_gset; | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||