Blender  V3.3
iterator.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved.
3  * 2003-2009 Blender Foundation.
4  * 2005-2006 Peter Schlaile <peter [at] schlaile [dot] de> */
5 
10 #include <string.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "DNA_scene_types.h"
15 #include "DNA_sequence_types.h"
16 
17 #include "BLI_ghash.h"
18 #include "BLI_listbase.h"
19 
20 #include "BKE_scene.h"
21 
22 #include "SEQ_iterator.h"
23 #include "SEQ_relations.h"
24 #include "SEQ_render.h"
25 #include "SEQ_time.h"
26 #include "render.h"
27 
28 /* -------------------------------------------------------------------- */
32 bool SEQ_iterator_ensure(SeqCollection *collection, SeqIterator *iterator, Sequence **r_seq)
33 {
34  if (iterator->iterator_initialized) {
35  return true;
36  }
37 
38  if (BLI_gset_len(collection->set) == 0) {
39  return false;
40  }
41 
42  iterator->collection = collection;
43  BLI_gsetIterator_init(&iterator->gsi, iterator->collection->set);
44  iterator->iterator_initialized = true;
45 
46  *r_seq = BLI_gsetIterator_getKey(&iterator->gsi);
47  BLI_gsetIterator_step(&iterator->gsi);
48 
49  return true;
50 }
51 
53 {
54  Sequence *seq = BLI_gsetIterator_done(&iterator->gsi) ? NULL :
55  BLI_gsetIterator_getKey(&iterator->gsi);
56  BLI_gsetIterator_step(&iterator->gsi);
57  return seq;
58 }
59 
61 {
62  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
63  if (!callback(seq, user_data)) {
64  /* Callback signaled stop, return. */
65  return false;
66  }
67  if (seq->type == SEQ_TYPE_META) {
68  if (!seq_for_each_recursive(&seq->seqbase, callback, user_data)) {
69  return false;
70  }
71  }
72  }
73  return true;
74 }
75 
77 {
79 }
80 
82 {
83  BLI_gset_free(collection->set, NULL);
84  MEM_freeN(collection);
85 }
86 
88 {
89  SeqCollection *collection = MEM_callocN(sizeof(SeqCollection), name);
90  collection->set = BLI_gset_new(
91  BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "SeqCollection GSet");
92  return collection;
93 }
94 
96 {
97  return BLI_gset_len(collection->set);
98 }
99 
100 bool SEQ_collection_has_strip(const Sequence *seq, const SeqCollection *collection)
101 {
102  return BLI_gset_haskey(collection->set, seq);
103 }
104 
106  const Scene *scene,
107  ListBase *seqbase,
108  void seq_query_func(const Scene *scene,
109  Sequence *seq_reference,
110  ListBase *seqbase,
111  SeqCollection *collection))
112 {
113  SeqCollection *collection = SEQ_collection_create(__func__);
114  seq_query_func(scene, seq_reference, seqbase, collection);
115  return collection;
116 }
118 {
119  void **key;
120  if (BLI_gset_ensure_p_ex(collection->set, seq, &key)) {
121  return false;
122  }
123 
124  *key = (void *)seq;
125  return true;
126 }
127 
129 {
130  return BLI_gset_remove(collection->set, seq, NULL);
131 }
132 
133 void SEQ_collection_merge(SeqCollection *collection_dst, SeqCollection *collection_src)
134 {
135  Sequence *seq;
136  SEQ_ITERATOR_FOREACH (seq, collection_src) {
137  SEQ_collection_append_strip(seq, collection_dst);
138  }
139  SEQ_collection_free(collection_src);
140 }
141 
142 void SEQ_collection_exclude(SeqCollection *collection, SeqCollection *exclude_elements)
143 {
144  Sequence *seq;
145  SEQ_ITERATOR_FOREACH (seq, exclude_elements) {
146  SEQ_collection_remove_strip(seq, collection);
147  }
148  SEQ_collection_free(exclude_elements);
149 }
150 
152  ListBase *seqbase,
153  SeqCollection *collection,
154  void seq_query_func(const Scene *scene,
155  Sequence *seq_reference,
156  ListBase *seqbase,
157  SeqCollection *collection))
158 {
159  /* Collect expanded results for each sequence in provided SeqIteratorCollection. */
160  SeqCollection *query_matches = SEQ_collection_create(__func__);
161 
162  Sequence *seq;
163  SEQ_ITERATOR_FOREACH (seq, collection) {
164  SEQ_collection_merge(query_matches,
165  SEQ_query_by_reference(seq, scene, seqbase, seq_query_func));
166  }
167 
168  /* Merge all expanded results in provided SeqIteratorCollection. */
169  SEQ_collection_merge(collection, query_matches);
170 }
171 
173 {
174  SeqCollection *duplicate = SEQ_collection_create(__func__);
175  Sequence *seq;
176  SEQ_ITERATOR_FOREACH (seq, collection) {
177  SEQ_collection_append_strip(seq, duplicate);
178  }
179  return duplicate;
180 }
181 
184 static void query_all_strips_recursive(ListBase *seqbase, SeqCollection *collection)
185 {
186  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
187  if (seq->type == SEQ_TYPE_META) {
188  query_all_strips_recursive(&seq->seqbase, collection);
189  }
190  SEQ_collection_append_strip(seq, collection);
191  }
192 }
193 
195 {
196  SeqCollection *collection = SEQ_collection_create(__func__);
197  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
198  if (seq->type == SEQ_TYPE_META) {
199  query_all_strips_recursive(&seq->seqbase, collection);
200  }
201  SEQ_collection_append_strip(seq, collection);
202  }
203  return collection;
204 }
205 
207 {
208  SeqCollection *collection = SEQ_collection_create(__func__);
209  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
210  SEQ_collection_append_strip(seq, collection);
211  }
212  return collection;
213 }
214 
216 {
217  SeqCollection *collection = SEQ_collection_create(__func__);
218  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
219  if ((seq->flag & SELECT) == 0) {
220  continue;
221  }
222  SEQ_collection_append_strip(seq, collection);
223  }
224  return collection;
225 }
226 
228  ListBase *seqbase,
229  const int timeline_frame)
230 {
231  SeqCollection *collection = SEQ_collection_create(__func__);
232 
233  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
234  if (SEQ_time_strip_intersects_frame(scene, seq, timeline_frame)) {
235  SEQ_collection_append_strip(seq, collection);
236  }
237  }
238  return collection;
239 }
240 
241 static void collection_filter_channel_up_to_incl(SeqCollection *collection, const int channel)
242 {
243  Sequence *seq;
244  SEQ_ITERATOR_FOREACH (seq, collection) {
245  if (seq->machine <= channel) {
246  continue;
247  }
248  SEQ_collection_remove_strip(seq, collection);
249  }
250 }
251 
252 /* Check if seq must be rendered. This depends on whole stack in some cases, not only seq itself.
253  * Order of applying these conditions is important. */
254 static bool must_render_strip(const Sequence *seq, SeqCollection *strips_at_timeline_frame)
255 {
256  bool seq_have_effect_in_stack = false;
257  Sequence *seq_iter;
258  SEQ_ITERATOR_FOREACH (seq_iter, strips_at_timeline_frame) {
259  /* Strips is below another strip with replace blending are not rendered. */
260  if (seq_iter->blend_mode == SEQ_BLEND_REPLACE && seq->machine < seq_iter->machine) {
261  return false;
262  }
263 
264  if ((seq_iter->type & SEQ_TYPE_EFFECT) != 0 &&
265  SEQ_relation_is_effect_of_strip(seq_iter, seq)) {
266  /* Strips in same channel or higher than its effect are rendered. */
267  if (seq->machine >= seq_iter->machine) {
268  return true;
269  }
270  /* Mark that this strip has effect in stack, that is above the strip. */
271  seq_have_effect_in_stack = true;
272  }
273  }
274 
275  /* All effects are rendered (with respect to conditions above). */
276  if ((seq->type & SEQ_TYPE_EFFECT) != 0) {
277  return true;
278  }
279 
280  /* If strip has effects in stack, and all effects are above this strip, it is not rendered. */
281  if (seq_have_effect_in_stack) {
282  return false;
283  }
284 
285  return true;
286 }
287 
288 /* Remove strips we don't want to render from collection. */
290 {
291  Sequence *seq;
292 
293  /* Remove sound strips and muted strips from collection, because these are not rendered.
294  * Function #must_render_strip() don't have to check for these strips anymore. */
295  SEQ_ITERATOR_FOREACH (seq, collection) {
296  if (seq->type == SEQ_TYPE_SOUND_RAM || SEQ_render_is_muted(channels, seq)) {
297  SEQ_collection_remove_strip(seq, collection);
298  }
299  }
300 
301  SEQ_ITERATOR_FOREACH (seq, collection) {
302  if (must_render_strip(seq, collection)) {
303  continue;
304  }
305  SEQ_collection_remove_strip(seq, collection);
306  }
307 }
308 
311  ListBase *seqbase,
312  const int timeline_frame,
313  const int displayed_channel)
314 {
315  SeqCollection *collection = query_strips_at_frame(scene, seqbase, timeline_frame);
316  if (displayed_channel != 0) {
317  collection_filter_channel_up_to_incl(collection, displayed_channel);
318  }
320  return collection;
321 }
322 
324 {
325  SeqCollection *collection = SEQ_collection_create(__func__);
326  LISTBASE_FOREACH (Sequence *, seq, seqbase) {
327  if ((seq->flag & SELECT) != 0) {
328  continue;
329  }
330  SEQ_collection_append_strip(seq, collection);
331  }
332  return collection;
333 }
334 
336  Sequence *seq_reference,
337  ListBase *seqbase,
338  SeqCollection *collection)
339 {
340  if (!SEQ_collection_append_strip(seq_reference, collection)) {
341  return; /* Strip is already in set, so all effects connected to it are as well. */
342  }
343 
344  /* Find all strips that seq_reference is connected to. */
345  if (seq_reference->type & SEQ_TYPE_EFFECT) {
346  if (seq_reference->seq1) {
347  SEQ_query_strip_effect_chain(scene, seq_reference->seq1, seqbase, collection);
348  }
349  if (seq_reference->seq2) {
350  SEQ_query_strip_effect_chain(scene, seq_reference->seq2, seqbase, collection);
351  }
352  if (seq_reference->seq3) {
353  SEQ_query_strip_effect_chain(scene, seq_reference->seq3, seqbase, collection);
354  }
355  }
356 
357  /* Find all strips connected to seq_reference. */
358  LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
359  if (seq_test->seq1 == seq_reference || seq_test->seq2 == seq_reference ||
360  seq_test->seq3 == seq_reference) {
361  SEQ_query_strip_effect_chain(scene, seq_test, seqbase, collection);
362  }
363  }
364 }
365 
367 {
368  Sequence *seq;
369  SEQ_ITERATOR_FOREACH (seq, collection) {
370  if ((seq->flag & SELECT) == 0) {
371  SEQ_collection_remove_strip(seq, collection);
372  }
373  }
374 }
bool BLI_gset_ensure_p_ex(GSet *gs, const void *key, void ***r_key)
Definition: BLI_ghash.c:974
bool BLI_gset_haskey(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1007
unsigned int BLI_ghashutil_ptrhash(const void *key)
GSet * BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:947
BLI_INLINE bool BLI_gsetIterator_done(const GSetIterator *gsi)
Definition: BLI_ghash.h:466
unsigned int BLI_gset_len(const GSet *gs) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:957
bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
BLI_INLINE void BLI_gsetIterator_init(GSetIterator *gsi, GSet *gs)
Definition: BLI_ghash.h:450
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
BLI_INLINE void BLI_gsetIterator_step(GSetIterator *gsi)
Definition: BLI_ghash.h:462
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
Definition: BLI_ghash.h:458
bool BLI_gset_remove(GSet *gs, const void *key, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1002
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
unsigned int uint
Definition: BLI_sys_types.h:67
#define SEQ_BLEND_REPLACE
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_META
@ SEQ_TYPE_EFFECT
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
#define SEQ_ITERATOR_FOREACH(var, collection)
Definition: SEQ_iterator.h:35
bool(* SeqForEachFunc)(struct Sequence *seq, void *user_data)
Definition: SEQ_iterator.h:78
#define SELECT
Scene scene
void * user_data
DEGForeachIDComponentCallback callback
Sequence * SEQ_iterator_yield(SeqIterator *iterator)
Definition: iterator.c:52
void SEQ_collection_exclude(SeqCollection *collection, SeqCollection *exclude_elements)
Definition: iterator.c:142
SeqCollection * SEQ_query_by_reference(Sequence *seq_reference, const Scene *scene, ListBase *seqbase, void seq_query_func(const Scene *scene, Sequence *seq_reference, ListBase *seqbase, SeqCollection *collection))
Definition: iterator.c:105
SeqCollection * SEQ_query_rendered_strips(const Scene *scene, ListBase *channels, ListBase *seqbase, const int timeline_frame, const int displayed_channel)
Definition: iterator.c:309
SeqCollection * SEQ_query_all_strips_recursive(ListBase *seqbase)
Definition: iterator.c:194
static bool seq_for_each_recursive(ListBase *seqbase, SeqForEachFunc callback, void *user_data)
Definition: iterator.c:60
void SEQ_collection_merge(SeqCollection *collection_dst, SeqCollection *collection_src)
Definition: iterator.c:133
uint SEQ_collection_len(const SeqCollection *collection)
Definition: iterator.c:95
void SEQ_filter_selected_strips(SeqCollection *collection)
Definition: iterator.c:366
void SEQ_query_strip_effect_chain(const Scene *scene, Sequence *seq_reference, ListBase *seqbase, SeqCollection *collection)
Definition: iterator.c:335
void SEQ_collection_expand(const Scene *scene, ListBase *seqbase, SeqCollection *collection, void seq_query_func(const Scene *scene, Sequence *seq_reference, ListBase *seqbase, SeqCollection *collection))
Definition: iterator.c:151
static void query_all_strips_recursive(ListBase *seqbase, SeqCollection *collection)
Definition: iterator.c:184
bool SEQ_iterator_ensure(SeqCollection *collection, SeqIterator *iterator, Sequence **r_seq)
Definition: iterator.c:32
bool SEQ_collection_remove_strip(Sequence *seq, SeqCollection *collection)
Definition: iterator.c:128
SeqCollection * SEQ_query_selected_strips(ListBase *seqbase)
Definition: iterator.c:215
SeqCollection * SEQ_query_all_strips(ListBase *seqbase)
Definition: iterator.c:206
SeqCollection * SEQ_collection_duplicate(SeqCollection *collection)
Definition: iterator.c:172
SeqCollection * SEQ_collection_create(const char *name)
Definition: iterator.c:87
static void collection_filter_channel_up_to_incl(SeqCollection *collection, const int channel)
Definition: iterator.c:241
static bool must_render_strip(const Sequence *seq, SeqCollection *strips_at_timeline_frame)
Definition: iterator.c:254
bool SEQ_collection_append_strip(Sequence *seq, SeqCollection *collection)
Definition: iterator.c:117
static void collection_filter_rendered_strips(ListBase *channels, SeqCollection *collection)
Definition: iterator.c:289
SeqCollection * SEQ_query_unselected_strips(ListBase *seqbase)
Definition: iterator.c:323
bool SEQ_collection_has_strip(const Sequence *seq, const SeqCollection *collection)
Definition: iterator.c:100
static SeqCollection * query_strips_at_frame(const Scene *scene, ListBase *seqbase, const int timeline_frame)
Definition: iterator.c:227
void SEQ_collection_free(SeqCollection *collection)
Definition: iterator.c:81
void SEQ_for_each_callback(ListBase *seqbase, SeqForEachFunc callback, void *user_data)
Definition: iterator.c:76
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
bool SEQ_render_is_muted(const ListBase *channels, const Sequence *seq)
Definition: render.c:2199
bool SEQ_relation_is_effect_of_strip(const Sequence *effect, const Sequence *input)
bool SEQ_time_strip_intersects_frame(const Scene *scene, const Sequence *seq, const int timeline_frame)
Definition: strip_time.c:437
struct GSet * set
Definition: SEQ_iterator.h:41
bool iterator_initialized
Definition: SEQ_iterator.h:47
GSetIterator gsi
Definition: SEQ_iterator.h:45
SeqCollection * collection
Definition: SEQ_iterator.h:46
struct Sequence * seq3
struct Sequence * seq1
struct Sequence * seq2