BLI: add high level documentation for core data structures #25

Merged
Jacques Lucke merged 14 commits from JacquesLucke/blender-developer-docs:core-data-structures into main 2024-02-19 19:09:34 +01:00
3 changed files with 33 additions and 2 deletions
Showing only changes of commit 1c2a43fdcc - Show all commits

View File

@ -21,7 +21,7 @@ std::string a = "A";
std::string b = "B"; std::string b = "B";
/* Get the CPPType for std::string. */ /* Get the CPPType for std::string. */
/* This only works when this CPPType has been defined elsewhere using BLI_CPP_TYPE_MAKE. */ /* This only works when BLI_CPP_TYPE_MAKE was used for the type. */
const CPPType &type = CPPType::get<std::string>(); const CPPType &type = CPPType::get<std::string>();
/* Swap values in a and b. */ /* Swap values in a and b. */

View File

@ -1 +1,31 @@
# Index Mask # Index Mask
An `IndexMask` ([source](https://projects.blender.org/blender/blender/src/branch/main/source/blender/blenlib/BLI_index_mask.hh)) is a sequence of unique and sorted indices. It's commonly used when a subset of elements in an array has to be processed. This is sometimes called [existential processing](https://www.dataorienteddesign.com/dodbook/node4.html) and is often better than having e.g. a bool for every element that has to be checked in every inner loop to determine if it has to be processed.
Semantically, an `IndexMask` is very similar to a simple `Vector<int64_t>` with unique and sorted indices. However, due to the implementation details of `IndexMask`, it can be significantly more efficient than the `Vector`.
An `IndexMask` does not own the memory it references. Typically, the referenced data is either statically allocated or is owned by an `IndexMaskMemory`.
```cpp
/* Owner of some dynamically allocated memory in one or more index masks. */
IndexMaskMemory memory;
/* Construct index mask for indices. */
const IndexMask mask = IndexMask::from_indices<int>({10, 12, 13, 14, ...}, memory);
/* Construct index mask from a boolean array. */
const IndexMask mask = IndexMask::from_bools(IndexRange(100), bool_span, memory);
/* Construct an index mask from a predicate. */
/* In this case, the index mask will contain every third index. */
/* The passed in grain size controls the level of parallelism. */
const IndexMask mask = IndexMask::from_predicate(
IndexRange(1000), GrainSize(512), memory,
[](const int64_t i) { return i % 3 == 0; });
/* Iterate over all indices in an index mask. */
mask.foreach_index([&](const int64_t i) { /* ... */ });
/* Work is parallelized when a grain size is passed in. */
mask.foreach_index(GrainSize(512), [&](const int64_t i) { /* ... */ });
```

View File

@ -17,7 +17,8 @@ VArray<int> values = VArray<int>::ForSingle(value, num_values);
VArray<int> values = VArray<int>::ForSpan(int_span); VArray<int> values = VArray<int>::ForSpan(int_span);
/* Create a virtual array where the value at each index is twice the index. */ /* Create a virtual array where the value at each index is twice the index. */
VArray<int> values = VArray<int>::ForFunc(num_values, [](const int64_t i) { return i * 2; }); VArray<int> values = VArray<int>::ForFunc(
num_values, [](const int64_t i) { return i * 2; });
/* Get the value at a specific index. */ /* Get the value at a specific index. */
int value = values[5]; int value = values[5];