diff options
133 files changed, 4413 insertions, 3691 deletions
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h index 084f573e8c7..5b15bb979f5 100644 --- a/source/blender/blenlib/BLI_array.h +++ b/source/blender/blenlib/BLI_array.h @@ -28,7 +28,7 @@ /** \name Internal defines * \{ */ -/** this returns the entire size of the array, including any buffering. */ +/** This returns the entire size of the array, including any buffering. */ #define _bli_array_totalsize_dynamic(arr) \ (((arr) == NULL) ? 0 : MEM_allocN_len(arr) / sizeof(*(arr))) @@ -44,8 +44,12 @@ /** * BLI_array.c * - * Doing the realloc in a macro isn't so simple, + * Doing the reallocation in a macro isn't so simple, * so use a function the macros can use. + * + * This function is only to be called via macros. + * + * \note The caller must adjust \a arr_len */ void _bli_array_grow_func(void **arr_p, const void *arr_static, @@ -64,8 +68,9 @@ void _bli_array_grow_func(void **arr_p, void *_##arr##_static = NULL /** - * this will use stack space, up to maxstatic array elements, before - * switching to dynamic heap allocation */ + * This will use stack space, up to `maxstatic` array elements, + * before switching to dynamic heap allocation. + */ #define BLI_array_staticdeclare(arr, maxstatic) \ int _##arr##_len = 0; \ char _##arr##_static[maxstatic * sizeof(*(arr))] @@ -77,7 +82,8 @@ void _bli_array_grow_func(void **arr_p, * Grow the array by a fixed number of items. * * Allow for a large 'num' value when the new size is more than double - * to allocate the exact sized array. */ + * to allocate the exact sized array. + */ #define BLI_array_reserve(arr, num) \ (void)((((void *)(arr) == NULL) && \ ((void *)(_##arr##_static) != \ @@ -95,12 +101,16 @@ void _bli_array_grow_func(void **arr_p, num, \ "BLI_array." #arr))) -/** returns length of array */ +/** + * Returns length of array. + */ #define BLI_array_grow_items(arr, num) (BLI_array_reserve(arr, num), (_##arr##_len += num)) #define BLI_array_grow_one(arr) BLI_array_grow_items(arr, 1) -/** appends an item to the array. */ +/** + * Appends an item to the array. + */ #define BLI_array_append(arr, item) \ ((void)BLI_array_grow_one(arr), (void)(arr[_##arr##_len - 1] = item)) @@ -111,7 +121,9 @@ void _bli_array_grow_func(void **arr_p, #define BLI_array_append_r(arr, item) \ ((void)BLI_array_grow_one(arr), (void)(arr[_##arr##_len - 1] = item), (&arr[_##arr##_len - 1])) -/** appends (grows) & returns a pointer to the uninitialized memory */ +/** + * Appends (grows) & returns a pointer to the uninitialized memory. + */ #define BLI_array_append_ret(arr) (BLI_array_reserve(arr, 1), &arr[(_##arr##_len++)]) #define BLI_array_free(arr) \ @@ -127,7 +139,8 @@ void _bli_array_grow_func(void **arr_p, /** * Resets the logical size of an array to zero, but doesn't - * free the memory. */ + * free the memory. + */ #define BLI_array_clear(arr) \ { \ _##arr##_len = 0; \ @@ -135,30 +148,32 @@ void _bli_array_grow_func(void **arr_p, ((void)0) /** - * Set the length of the array, doesn't actually increase the allocated array - * size. don't use this unless you know what you're doing. */ + * Set the length of the array, doesn't actually increase the allocated array size. + * Don't use this unless you know what you're doing. + */ #define BLI_array_len_set(arr, len) \ { \ _##arr##_len = (len); \ } \ ((void)0) -/** only to prevent unused warnings */ +/** + * Only to prevent unused warnings. + */ #define BLI_array_fake_user(arr) ((void)_##arr##_len, (void)_##arr##_static) /** \} */ /* -------------------------------------------------------------------- */ /** \name Generic Array Utils - * other useful defines - * (unrelated to the main array macros) * + * Other useful defines (unrelated to the main array macros). * \{ */ /** - * Not part of the 'API' but handy functions, - * same purpose as #BLI_array_staticdeclare() - * but use when the max size is known ahead of time */ + * Not part of the 'API' but handy functions, same purpose as #BLI_array_staticdeclare() + * but use when the max size is known ahead of time. + */ #define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \ char _##arr##_static[maxstatic * sizeof(*(arr))]; \ const bool _##arr##_is_static = ((void *)_##arr##_static) != \ diff --git a/source/blender/blenlib/BLI_array_store.h b/source/blender/blenlib/BLI_array_store.h index 78d718117ba..0be361d4ab9 100644 --- a/source/blender/blenlib/BLI_array_store.h +++ b/source/blender/blenlib/BLI_array_store.h @@ -28,25 +28,88 @@ extern "C" { typedef struct BArrayState BArrayState; typedef struct BArrayStore BArrayStore; +/** + * Create a new array store, which can store any number of arrays + * as long as their stride matches. + * + * \param stride: `sizeof()` each element, + * + * \note while a stride of `1` will always work, + * its less efficient since duplicate chunks of memory will be searched + * at positions unaligned with the array data. + * + * \param chunk_count: Number of elements to split each chunk into. + * - A small value increases the ability to de-duplicate chunks, + * but adds overhead by increasing the number of chunks to look up when searching for duplicates, + * as well as some overhead constructing the original array again, with more calls to `memcpy`. + * - Larger values reduce the *book keeping* overhead, + * but increase the chance a small, + * isolated change will cause a larger amount of data to be duplicated. + * + * \return A new array store, to be freed with #BLI_array_store_destroy. + */ BArrayStore *BLI_array_store_create(unsigned int stride, unsigned int chunk_count); +/** + * Free the #BArrayStore, including all states and chunks. + */ void BLI_array_store_destroy(BArrayStore *bs); +/** + * Clear all contents, allowing reuse of \a bs. + */ void BLI_array_store_clear(BArrayStore *bs); -/* find the memory used by all states (expanded & real) */ +/** + * Find the memory used by all states (expanded & real). + * + * \return the total amount of memory that would be used by getting the arrays for all states. + */ size_t BLI_array_store_calc_size_expanded_get(const BArrayStore *bs); +/** + * \return the amount of memory used by all #BChunk.data + * (duplicate chunks are only counted once). + */ size_t BLI_array_store_calc_size_compacted_get(const BArrayStore *bs); +/** + * + * \param data: Data used to create + * \param state_reference: The state to use as a reference when adding the new state, + * typically this is the previous state, + * however it can be any previously created state from this \a bs. + * + * \return The new state, + * which is used by the caller as a handle to get back the contents of \a data. + * This may be removed using #BLI_array_store_state_remove, + * otherwise it will be removed with #BLI_array_store_destroy. + */ BArrayState *BLI_array_store_state_add(BArrayStore *bs, const void *data, const size_t data_len, const BArrayState *state_reference); +/** + * Remove a state and free any unused #BChunk data. + * + * The states can be freed in any order. + */ void BLI_array_store_state_remove(BArrayStore *bs, BArrayState *state); +/** + * \return the expanded size of the array, + * use this to know how much memory to allocate #BLI_array_store_state_data_get's argument. + */ size_t BLI_array_store_state_size_get(BArrayState *state); +/** + * Fill in existing allocated memory with the contents of \a state. + */ void BLI_array_store_state_data_get(BArrayState *state, void *data); +/** + * Allocate an array for \a state and return it. + */ void *BLI_array_store_state_data_get_alloc(BArrayState *state, size_t *r_data_len); -/* only for tests */ +/** + * \note Only for tests. + */ bool BLI_array_store_is_valid(BArrayStore *bs); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_array_utils.h b/source/blender/blenlib/BLI_array_utils.h index 52d41173a0e..eb14b030bf9 100644 --- a/source/blender/blenlib/BLI_array_utils.h +++ b/source/blender/blenlib/BLI_array_utils.h @@ -28,12 +28,29 @@ extern "C" { #endif +/** + * In-place array reverse. + * + * Access via #BLI_array_reverse + */ void _bli_array_reverse(void *arr, uint arr_len, size_t arr_stride); #define BLI_array_reverse(arr, arr_len) _bli_array_reverse(arr, arr_len, sizeof(*(arr))) +/** + * In-place array wrap. + * (rotate the array one step forward or backwards). + * + * Access via #BLI_array_wrap + */ void _bli_array_wrap(void *arr, uint arr_len, size_t arr_stride, int dir); #define BLI_array_wrap(arr, arr_len, dir) _bli_array_wrap(arr, arr_len, sizeof(*(arr)), dir) +/** + *In-place array permute. + * (re-arrange elements based on an array of indices). + * + * Access via #BLI_array_wrap + */ void _bli_array_permute( void *arr, const uint arr_len, const size_t arr_stride, const uint *order, void *arr_temp); #define BLI_array_permute(arr, arr_len, order) \ @@ -41,13 +58,30 @@ void _bli_array_permute( #define BLI_array_permute_ex(arr, arr_len, order, arr_temp) \ _bli_array_permute(arr, arr_len, sizeof(*(arr)), order, arr_temp) +/** + * In-place array de-duplication of an ordered array. + * + * \return The new length of the array. + * + * Access via #BLI_array_deduplicate_ordered + */ uint _bli_array_deduplicate_ordered(void *arr, uint arr_len, size_t arr_stride); #define BLI_array_deduplicate_ordered(arr, arr_len) \ _bli_array_deduplicate_ordered(arr, arr_len, sizeof(*(arr))) +/** + * Find the first index of an item in an array. + * + * Access via #BLI_array_findindex + * + * \note Not efficient, use for error checks/asserts. + */ int _bli_array_findindex(const void *arr, uint arr_len, size_t arr_stride, const void *p); #define BLI_array_findindex(arr, arr_len, p) _bli_array_findindex(arr, arr_len, sizeof(*(arr)), p) +/** + * A version of #BLI_array_findindex that searches from the end of the list. + */ int _bli_array_rfindindex(const void *arr, uint arr_len, size_t arr_stride, const void *p); #define BLI_array_rfindindex(arr, arr_len, p) \ _bli_array_rfindindex(arr, arr_len, sizeof(*(arr)), p) @@ -66,6 +100,22 @@ void _bli_array_binary_or( CHECK_TYPE_PAIR_INLINE(*(arr), *(arr_b)), \ _bli_array_binary_or(arr, arr_a, arr_b, arr_len, sizeof(*(arr)))) +/** + * Utility function to iterate over contiguous items in an array. + * + * \param use_wrap: Detect contiguous ranges across the first/last points. + * In this case the second index of \a span_step may be lower than the first, + * which indicates the values are wrapped. + * \param use_delimit_bounds: When false, + * ranges that defined by the start/end indices are excluded. + * This option has no effect when \a use_wrap is enabled. + * \param test_fn: Function to test if the item should be included in the range. + * \param user_data: User data for \a test_fn. + * \param span_step: Indices to iterate over, + * initialize both values to the array length to initialize iteration. + * \param r_span_len: The length of the span, useful when \a use_wrap is enabled, + * where calculating the length isn't a simple subtraction. + */ bool _bli_array_iter_span(const void *arr, uint arr_len, size_t arr_stride, @@ -87,9 +137,19 @@ bool _bli_array_iter_span(const void *arr, span_step, \ r_span_len) +/** + * Simple utility to check memory is zeroed. + */ bool _bli_array_is_zeroed(const void *arr, uint arr_len, size_t arr_stride); #define BLI_array_is_zeroed(arr, arr_len) _bli_array_is_zeroed(arr, arr_len, sizeof(*(arr))) +/** + * Smart function to sample a rectangle spiraling outside. + * Nice for selection ID. + * + * \param arr_shape: dimensions [w, h]. + * \param center: coordinates [x, y] indicating where to start traversing. + */ bool _bli_array_iter_spiral_square(const void *arr_v, const int arr_shape[2], const size_t elem_size, diff --git a/source/blender/blenlib/BLI_astar.h b/source/blender/blenlib/BLI_astar.h index fe5c4ddad69..a1d4e28dad9 100644 --- a/source/blender/blenlib/BLI_astar.h +++ b/source/blender/blenlib/BLI_astar.h @@ -76,18 +76,52 @@ typedef struct BLI_AStarGraph { struct MemArena *mem; /* Memory arena. */ } BLI_AStarGraph; +/** + * Initialize a node in A* graph. + * + * \param custom_data: an opaque pointer attached to this link, + * available e.g. to cost callback function. + */ void BLI_astar_node_init(BLI_AStarGraph *as_graph, const int node_index, void *custom_data); +/** + * Add a link between two nodes of our A* graph. + * + * \param cost: The 'length' of the link + * (actual distance between two vertices or face centers e.g.). + * \param custom_data: An opaque pointer attached to this link, + * available e.g. to cost callback function. + */ void BLI_astar_node_link_add(BLI_AStarGraph *as_graph, const int node1_index, const int node2_index, const float cost, void *custom_data); +/** + * \return The index of the other node of given link. + */ int BLI_astar_node_link_other_node(BLI_AStarGNLink *lnk, const int idx); +/** + * Initialize a solution data for given A* graph. Does not compute anything! + * + * \param custom_data: an opaque pointer attached to this link, available e.g + * . to cost callback function. + * + * \note BLI_AStarSolution stores nearly all data needed during solution compute. + */ void BLI_astar_solution_init(BLI_AStarGraph *as_graph, BLI_AStarSolution *as_solution, void *custom_data); +/** + * Clear given solution's data, but does not release its memory. + * Avoids having to recreate/allocate a memarena in loops, e.g. + * + * \note This *has to be called* between each path solving. + */ void BLI_astar_solution_clear(BLI_AStarSolution *as_solution); +/** + * Release the memory allocated for this solution. + */ void BLI_astar_solution_free(BLI_AStarSolution *as_solution); /** @@ -108,8 +142,24 @@ typedef float (*astar_f_cost)(BLI_AStarGraph *as_graph, const int node_idx_next, const int node_idx_dst); +/** + * Initialize an A* graph. Total number of nodes must be known. + * + * Nodes might be e.g. vertices, faces, ... etc. + * + * \param custom_data: an opaque pointer attached to this link, + * available e.g. to cost callback function. + */ void BLI_astar_graph_init(BLI_AStarGraph *as_graph, const int node_num, void *custom_data); void BLI_astar_graph_free(BLI_AStarGraph *as_graph); +/** + * Solve a path in given graph, using given 'cost' callback function. + * + * \param max_steps: maximum number of nodes the found path may have. + * Useful in performance-critical usages. + * If no path is found within given steps, returns false too. + * \return true if a path was found, false otherwise. + */ bool BLI_astar_graph_solve(BLI_AStarGraph *as_graph, const int node_index_src, const int node_index_dst, diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h index c97be6eed3c..b5ef08e9e60 100644 --- a/source/blender/blenlib/BLI_bitmap.h +++ b/source/blender/blenlib/BLI_bitmap.h @@ -40,26 +40,38 @@ typedef unsigned int BLI_bitmap; /* 0b11111 */ #define _BITMAP_MASK 31 -/* number of blocks needed to hold '_tot' bits */ +/** + * Number of blocks needed to hold '_tot' bits. + */ #define _BITMAP_NUM_BLOCKS(_tot) (((_tot) >> _BITMAP_POWER) + 1) -/* size (in bytes) used to hold '_tot' bits */ +/** + * Size (in bytes) used to hold '_tot' bits. + */ #define BLI_BITMAP_SIZE(_tot) ((size_t)(_BITMAP_NUM_BLOCKS(_tot)) * sizeof(BLI_bitmap)) -/* allocate memory for a bitmap with '_tot' bits; free with MEM_freeN() */ +/** + * Allocate memory for a bitmap with '_tot' bits; free with MEM_freeN(). + */ #define BLI_BITMAP_NEW(_tot, _alloc_string) \ ((BLI_bitmap *)MEM_callocN(BLI_BITMAP_SIZE(_tot), _alloc_string)) -/* allocate a bitmap on the stack */ +/** + * Allocate a bitmap on the stack. + */ #define BLI_BITMAP_NEW_ALLOCA(_tot) \ ((BLI_bitmap *)memset(alloca(BLI_BITMAP_SIZE(_tot)), 0, BLI_BITMAP_SIZE(_tot))) -/* Allocate using given MemArena */ +/** + * Allocate using given MemArena. + */ #define BLI_BITMAP_NEW_MEMARENA(_mem, _tot) \ (CHECK_TYPE_INLINE(_mem, MemArena *), \ ((BLI_bitmap *)BLI_memarena_calloc(_mem, BLI_BITMAP_SIZE(_tot)))) -/* get the value of a single bit at '_index' */ +/** + * Get the value of a single bit at '_index'. + */ #define BLI_BITMAP_TEST(_bitmap, _index) \ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \ ((_bitmap)[(_index) >> _BITMAP_POWER] & (1u << ((_index)&_BITMAP_MASK)))) @@ -74,22 +86,30 @@ typedef unsigned int BLI_bitmap; (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \ (BLI_BITMAP_TEST(_bitmap, _index) != 0)) -/* set the value of a single bit at '_index' */ +/** + * Set the value of a single bit at '_index'. + */ #define BLI_BITMAP_ENABLE(_bitmap, _index) \ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \ ((_bitmap)[(_index) >> _BITMAP_POWER] |= (1u << ((_index)&_BITMAP_MASK)))) -/* clear the value of a single bit at '_index' */ +/** + * Clear the value of a single bit at '_index'. + */ #define BLI_BITMAP_DISABLE(_bitmap, _index) \ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \ ((_bitmap)[(_index) >> _BITMAP_POWER] &= ~(1u << ((_index)&_BITMAP_MASK)))) -/* flip the value of a single bit at '_index' */ +/** + * Flip the value of a single bit at '_index'. + */ #define BLI_BITMAP_FLIP(_bitmap, _index) \ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \ ((_bitmap)[(_index) >> _BITMAP_POWER] ^= (1u << ((_index)&_BITMAP_MASK)))) -/* set or clear the value of a single bit at '_index' */ +/** + * Set or clear the value of a single bit at '_index'. + */ #define BLI_BITMAP_SET(_bitmap, _index, _set) \ { \ CHECK_TYPE(_bitmap, BLI_bitmap *); \ @@ -102,7 +122,9 @@ typedef unsigned int BLI_bitmap; } \ (void)0 -/* resize bitmap to have space for '_tot' bits */ +/** + * Resize bitmap to have space for '_tot' bits. + */ #define BLI_BITMAP_RESIZE(_bitmap, _tot) \ { \ CHECK_TYPE(_bitmap, BLI_bitmap *); \ @@ -110,10 +132,25 @@ typedef unsigned int BLI_bitmap; } \ (void)0 +/** + * Set or clear all bits in the bitmap. + */ void BLI_bitmap_set_all(BLI_bitmap *bitmap, bool set, size_t bits); +/** + * Invert all bits in the bitmap. + */ void BLI_bitmap_flip_all(BLI_bitmap *bitmap, size_t bits); +/** + * Copy all bits from one bitmap to another. + */ void BLI_bitmap_copy_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits); +/** + * Combine two bitmaps with boolean AND. + */ void BLI_bitmap_and_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits); +/** + * Combine two bitmaps with boolean OR. + */ void BLI_bitmap_or_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_bitmap_draw_2d.h b/source/blender/blenlib/BLI_bitmap_draw_2d.h index 8331d8fac08..1b9ff2162e3 100644 --- a/source/blender/blenlib/BLI_bitmap_draw_2d.h +++ b/source/blender/blenlib/BLI_bitmap_draw_2d.h @@ -24,17 +24,37 @@ extern "C" { #endif +/** + * Plot a line from \a p1 to \a p2 (inclusive). + * + * \note For clipped line drawing, see: http://stackoverflow.com/a/40902741/432509 + */ void BLI_bitmap_draw_2d_line_v2v2i(const int p1[2], const int p2[2], bool (*callback)(int, int, void *), void *user_data); +/** + * \note Unclipped (clipped version can be added if needed). + */ void BLI_bitmap_draw_2d_tri_v2i(const int p1[2], const int p2[2], const int p3[2], void (*callback)(int x, int x_end, int y, void *), void *user_data); +/** + * Draws a filled polygon with support for self intersections. + * + * \param callback: Takes the x, y coords and x-span (\a x_end is not inclusive), + * note that \a x_end will always be greater than \a x, so we can use: + * + * \code{.c} + * do { + * func(x, y); + * } while (++x != x_end); + * \endcode + */ void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin, const int ymin, const int xmax, diff --git a/source/blender/blenlib/BLI_boxpack_2d.h b/source/blender/blenlib/BLI_boxpack_2d.h index 7e347d0b0d7..e743424db59 100644 --- a/source/blender/blenlib/BLI_boxpack_2d.h +++ b/source/blender/blenlib/BLI_boxpack_2d.h @@ -44,6 +44,20 @@ typedef struct BoxPack { int index; } BoxPack; +/** + * Main box-packing function accessed from other functions + * This sets boxes x,y to positive values, sorting from 0,0 outwards. + * There is no limit to the space boxes may take, only that they will be packed + * tightly into the lower left hand corner (0,0) + * + * \param boxarray: a pre-allocated array of boxes. + * only the 'box->x' and 'box->y' are set, 'box->w' and 'box->h' are used, + * 'box->index' is not used at all, the only reason its there + * is that the box array is sorted by area and programs need to be able + * to have some way of writing the boxes back to the original data. + * \param len: the number of boxes in the array. + * \param r_tot_x, r_tot_y: set so you can normalize the data. + */ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *r_tot_x, float *r_tot_y); typedef struct FixedSizeBoxPack { @@ -52,6 +66,21 @@ typedef struct FixedSizeBoxPack { int w, h; } FixedSizeBoxPack; +/** + * Packs boxes into a fixed area. + * + * Boxes and packed are linked lists containing structs that can be cast to + * #FixedSizeBoxPack (i.e. contains a #FixedSizeBoxPack as its first element). + * Boxes that were packed successfully are placed into *packed and removed from *boxes. + * + * The algorithm is a simplified version of https://github.com/TeamHypersomnia/rectpack2D. + * Better ones could be used, but for the current use case (packing Image tiles into GPU + * textures) this is fine. + * + * Note that packing efficiency depends on the order of the input boxes. Generally speaking, + * larger boxes should come first, though how exactly size is best defined (e.g. area, perimeter) + * depends on the particular application. + */ void BLI_box_pack_2d_fixedarea(struct ListBase *boxes, int width, int height, diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h index 9d66fe9a14e..7f577443cf7 100644 --- a/source/blender/blenlib/BLI_buffer.h +++ b/source/blender/blenlib/BLI_buffer.h @@ -71,13 +71,25 @@ enum { } \ (void)0 -/* Never decreases the amount of memory allocated */ +/** + * \note Never decreases the amount of memory allocated. + */ void BLI_buffer_resize(BLI_Buffer *buffer, const size_t new_count); -/* Ensure size, throwing away old data, respecting BLI_BUFFER_USE_CALLOC */ +/** + * Ensure size, throwing away old data, respecting #BLI_BUFFER_USE_CALLOC. + * + * Similar to #BLI_buffer_resize, but use when the existing data can be: + * - Ignored (malloc'd). + * - Cleared (when #BLI_BUFFER_USE_CALLOC is set). + */ void BLI_buffer_reinit(BLI_Buffer *buffer, const size_t new_count); -/* Append an array of elements. */ +/** + * Append an array of elements. + * + * Callers use #BLI_buffer_append_array. + */ void _bli_buffer_append_array(BLI_Buffer *buffer, void *data, size_t count); #define BLI_buffer_append_array(buffer_, type_, data_, count_) \ { \ @@ -87,7 +99,11 @@ void _bli_buffer_append_array(BLI_Buffer *buffer, void *data, size_t count); } \ (void)0 -/* Does not free the buffer structure itself */ +/** + * Does not free the buffer structure itself. + * + * Callers use #BLI_buffer_free. + */ void _bli_buffer_free(BLI_Buffer *buffer); #define BLI_buffer_free(name_) \ { \ @@ -96,7 +112,9 @@ void _bli_buffer_free(BLI_Buffer *buffer); } \ (void)0 -/* A buffer embedded in a struct. Using memcpy is allowed until first resize. */ +/** + * A buffer embedded in a struct. Using #memcpy is allowed until first resize. + */ #define BLI_buffer_field_init(name_, type_) \ { \ memset(name_, 0, sizeof(*name_)); \ diff --git a/source/blender/blenlib/BLI_convexhull_2d.h b/source/blender/blenlib/BLI_convexhull_2d.h index e930117822f..44758fb3880 100644 --- a/source/blender/blenlib/BLI_convexhull_2d.h +++ b/source/blender/blenlib/BLI_convexhull_2d.h @@ -24,10 +24,43 @@ extern "C" { #endif +/** + * A.M. Andrew's monotone chain 2D convex hull algorithm. + * + * \param points: An array of 2D points presorted by increasing x and y-coords. + * \param n: The number of points in points. + * \param r_points: An array of the convex hull vertex indices (max is n). + * \returns the number of points in r_points. + */ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points[]); +/** + * A.M. Andrew's monotone chain 2D convex hull algorithm. + * + * \param points: An array of 2D points. + * \param n: The number of points in points. + * \param r_points: An array of the convex hull vertex indices (max is n). + * _must_ be allocated as `n * 2` because of how its used internally, + * even though the final result will be no more than \a n in size. + * \returns the number of points in r_points. + */ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[]); +/** + * \return The best angle for fitting the convex hull to an axis aligned bounding box. + * + * Intended to be used with #BLI_convexhull_2d + * + * \param points_hull: Ordered hull points + * (result of #BLI_convexhull_2d mapped to a contiguous array). + * + * \note we could return the index of the best edge too if its needed. + */ float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n); +/** + * Wrap #BLI_convexhull_aabb_fit_hull_2d and do the convex hull calculation. + * + * \param points: arbitrary 2d points. + */ float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_dlrbTree.h b/source/blender/blenlib/BLI_dlrbTree.h index 03aab8d2895..5226d1999be 100644 --- a/source/blender/blenlib/BLI_dlrbTree.h +++ b/source/blender/blenlib/BLI_dlrbTree.h @@ -21,23 +21,24 @@ /** \file * \ingroup bli - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Double-Linked Red-Black Tree Implementation: + * + * Double-Linked Red-Black Tree Implementation: * * This is simply a Red-Black Tree implementation whose nodes can later * be arranged + retrieved as elements in a Double-Linked list (i.e. ListBase). * The Red-Black Tree implementation is based on the methods defined by Wikipedia. */ +#ifdef __cplusplus +extern "C" { +#endif + /* ********************************************** */ /* Data Types and Type Defines */ -/* Base Structs --------------------------------- */ +/* -------------------------------------------------------------------- */ +/** \name Base Structs + * \{ */ /* Basic Layout for a Node */ typedef struct DLRBT_Node { @@ -69,102 +70,149 @@ typedef struct DLRBT_Tree { void *root; /* this should be based on DLRBT_Node-s */ } DLRBT_Tree; -/* Callback Types --------------------------------- */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callback Types + * \{ */ -/* Return -1, 0, 1 for whether the given data is less than, +/** + * Return -1, 0, 1 for whether the given data is less than, * equal to, or greater than the given node. - * - node: <DLRBT_Node> the node to compare to. - * - data: pointer to the relevant data or values stored in the bit-pattern. - * dependent on the function. + * \param node: <DLRBT_Node> the node to compare to. + * \param data: pointer to the relevant data or values stored in the bit-pattern. + * Dependent on the function. */ typedef short (*DLRBT_Comparator_FP)(void *node, void *data); -/* Return a new node instance wrapping the given data - * - data: Pointer to the relevant data to create a subclass of node from +/** + * Return a new node instance wrapping the given data + * - data: Pointer to the relevant data to create a subclass of node from. */ typedef DLRBT_Node *(*DLRBT_NAlloc_FP)(void *data); -/* Update an existing node instance accordingly to be in sync with the given data. - * - node: <DLRBT_Node> the node to update. - * - data: Pointer to the relevant data or values stored in the bit-pattern. - * dependent on the function. +/** + * Update an existing node instance accordingly to be in sync with the given data. + * \param node: <DLRBT_Node> the node to update. + * \param data: Pointer to the relevant data or values stored in the bit-pattern. + * Dependent on the function. */ typedef void (*DLRBT_NUpdate_FP)(void *node, void *data); /* ********************************************** */ /* Public API */ -/* ADT Management ------------------------------- */ +/** \} */ -/* Create a new tree, and initialize as necessary */ +/* -------------------------------------------------------------------- */ +/** \name ADT Management + * \{ */ + +/** + * Create a new tree, and initialize as necessary. + */ DLRBT_Tree *BLI_dlrbTree_new(void); -/* Initializes some given trees */ +/** + * Initializes some given trees. + * Just zero out the pointers used. + */ void BLI_dlrbTree_init(DLRBT_Tree *tree); -/* Free some tree */ +/** + * Free the given tree's data but not the tree itself. + */ void BLI_dlrbTree_free(DLRBT_Tree *tree); -/* Make sure the tree's Double-Linked list representation is valid */ +/** + * Make sure the tree's Double-Linked list representation is valid. + */ void BLI_dlrbTree_linkedlist_sync(DLRBT_Tree *tree); -/* Searching ------------------------------------ */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Tree Searching Utilities + * \{ */ -/* Find the node which matches or is the closest to the requested node */ +/** + * Find the node which matches or is the closest to the requested node. + */ DLRBT_Node *BLI_dlrbTree_search(const DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data); -/* Find the node which exactly matches the required data */ +/** + * Find the node which exactly matches the required data. + */ DLRBT_Node *BLI_dlrbTree_search_exact(const DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data); -/* Find the node which occurs immediately before the best matching node */ +/** + * Find the node which occurs immediately before the best matching node. + */ DLRBT_Node *BLI_dlrbTree_search_prev(const DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data); -/* Find the node which occurs immediately after the best matching node */ +/** + * Find the node which occurs immediately after the best matching node. + */ DLRBT_Node *BLI_dlrbTree_search_next(const DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data); -/* Check whether there is a node matching the requested node */ +/** + * Check whether there is a node matching the requested node. + */ short BLI_dlrbTree_contains(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data); -/* Node Operations (Managed) --------------------- */ -/* These methods automate the process of adding/removing nodes from the BST, - * using the supplied data and callbacks +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Node Operations (Managed) + * \{ */ + +/** + * These methods automate the process of adding/removing nodes from the BST, + * using the supplied data and callbacks. */ -/* Add the given data to the tree, and return the node added */ -/* NOTE: for duplicates, the update_cb is called (if available), - * and the existing node is returned. */ +/** + * Add the given data to the tree, and return the node added. + * \note for duplicates, the update_cb is called (if available), + * and the existing node is returned. + */ DLRBT_Node *BLI_dlrbTree_add(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, DLRBT_NAlloc_FP new_cb, DLRBT_NUpdate_FP update_cb, void *data); -/* Remove the given element from the tree and balance again */ -/* FIXME: this is not implemented yet... */ +/* FIXME: this is not implemented yet. */ +/** + * Remove the given element from the tree and balance again. + */ // void BLI_dlrbTree_remove(DLRBT_Tree *tree, DLRBT_Node *node); -/* Node Operations (Manual) --------------------- */ -/* These methods require custom code for creating BST nodes and adding them to the +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Node Operations (Manual) + * + * These methods require custom code for creating BST nodes and adding them to the * tree in special ways, such that the node can then be balanced. * - * It is recommended that these methods are only used where the other method is too cumbersome... - */ + * It is recommended that these methods are only used where the other method is too cumbersome. + * \{ */ -/* Balance the tree after the given node has been added to it +/** + * Balance the tree after the given node has been added to it * (using custom code, in the Binary Tree way). */ void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node); -/* ********************************************** */ - #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_dynstr.h b/source/blender/blenlib/BLI_dynstr.h index 4df773c7cc6..90d93f29bcb 100644 --- a/source/blender/blenlib/BLI_dynstr.h +++ b/source/blender/blenlib/BLI_dynstr.h @@ -39,25 +39,85 @@ extern "C" { struct DynStr; -/** The abstract DynStr type */ +/** The abstract DynStr type. */ typedef struct DynStr DynStr; +/** + * Create a new #DynStr. + * + * \return Pointer to a new #DynStr. + */ DynStr *BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +/** + * Create a new #DynStr. + * + * \return Pointer to a new #DynStr. + */ DynStr *BLI_dynstr_new_memarena(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +/** + * Append a c-string to a #DynStr. + * + * \param ds: The #DynStr to append to. + * \param cstr: The c-string to append. + */ void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL(); +/** + * Append a length clamped c-string to a #DynStr. + * + * \param ds: The #DynStr to append to. + * \param cstr: The c-string to append. + * \param len: The maximum length of the c-string to copy. + */ void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len) ATTR_NONNULL(); +/** + * Append a c-string to a #DynStr, but with formatting like `printf`. + * + * \param ds: The #DynStr to append to. + * \param format: The `printf` format string to use. + */ void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format, ...) ATTR_PRINTF_FORMAT(2, 3) ATTR_NONNULL(1, 2); void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format, va_list args) ATTR_PRINTF_FORMAT(2, 0) ATTR_NONNULL(1, 2); +/** + * Find the length of a #DynStr. + * + * \param ds: The #DynStr of interest. + * \return The length of \a ds. + */ int BLI_dynstr_get_len(const DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Get a #DynStr's contents as a c-string. + * \return The c-string which must be freed using #MEM_freeN. + * + * \param ds: The #DynStr of interest. + * \return The contents of \a ds as a c-string. + */ char *BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Get a #DynStr's contents as a c-string. + * The \a rets argument must be allocated to be at + * least the size of `BLI_dynstr_get_len(ds) + 1`. + * + * \param ds: The DynStr of interest. + * \param rets: The string to fill. + */ void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets) ATTR_NONNULL(); +/** + * Clear the #DynStr + * + * \param ds: The DynStr to clear. + */ void BLI_dynstr_clear(DynStr *ds) ATTR_NONNULL(); +/** + * Free the #DynStr + * + * \param ds: The DynStr to free. + */ void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL(); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h index 41f0d41d1e0..b0f71655c19 100644 --- a/source/blender/blenlib/BLI_edgehash.h +++ b/source/blender/blenlib/BLI_edgehash.h @@ -48,42 +48,120 @@ typedef struct EdgeHashIterator { typedef void (*EdgeHashFreeFP)(void *key); enum { - EDGEHASH_FLAG_ALLOW_DUPES = (1 << 0), /* only checked for in debug mode */ + /** + * Only checked for in debug mode. + */ + EDGEHASH_FLAG_ALLOW_DUPES = (1 << 0), }; EdgeHash *BLI_edgehash_new_ex(const char *info, const unsigned int nentries_reserve); EdgeHash *BLI_edgehash_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP free_value); void BLI_edgehash_print(EdgeHash *eh); +/** + * Insert edge (\a v0, \a v1) into hash with given value, does + * not check for duplicates. + */ void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val); +/** + * Assign a new value to a key that may already be in edgehash. + */ bool BLI_edgehash_reinsert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val); +/** + * Return value for given edge (\a v0, \a v1), or NULL if + * if key does not exist in hash. (If need exists + * to differentiate between key-value being NULL and + * lack of key then see #BLI_edgehash_lookup_p(). + */ void *BLI_edgehash_lookup(const EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; +/** + * A version of #BLI_edgehash_lookup which accepts a fallback argument. + */ void *BLI_edgehash_lookup_default(const EdgeHash *eh, unsigned int v0, unsigned int v1, void *default_value) ATTR_WARN_UNUSED_RESULT; +/** + * Return pointer to value for given edge (\a v0, \a v1), + * or NULL if key does not exist in hash. + */ void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; +/** + * Ensure \a (v0, v1) is exists in \a eh. + * + * This handles the common situation where the caller needs ensure a key is added to \a eh, + * constructing a new value in the case the key isn't found. + * Otherwise use the existing value. + * + * Such situations typically incur multiple lookups, however this function + * avoids them by ensuring the key is added, + * returning a pointer to the value so it can be used or initialized by the caller. + * + * \return true when the value didn't need to be added. + * (when false, the caller _must_ initialize the value). + */ bool BLI_edgehash_ensure_p(EdgeHash *eh, unsigned int v0, unsigned int v1, void ***r_val) ATTR_WARN_UNUSED_RESULT; +/** + * Remove \a key (v0, v1) from \a eh, or return false if the key wasn't found. + * + * \param v0, v1: The key to remove. + * \param free_value: Optional callback to free the value. + * \return true if \a key was removed from \a eh. + */ bool BLI_edgehash_remove(EdgeHash *eh, unsigned int v0, unsigned int v1, EdgeHashFreeFP free_value); +/** + * Remove \a key (v0, v1) from \a eh, returning the value or NULL if the key wasn't found. + * + * \param v0, v1: The key to remove. + * \return the value of \a key int \a eh or NULL. + */ void *BLI_edgehash_popkey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; +/** + * Return boolean true/false if edge (v0,v1) in hash. + */ bool BLI_edgehash_haskey(const EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; +/** + * Return number of keys in hash. + */ int BLI_edgehash_len(const EdgeHash *eh) ATTR_WARN_UNUSED_RESULT; +/** + * Remove all edges from hash. + */ void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP free_value, const uint reserve); +/** + * Wraps #BLI_edgehash_clear_ex with zero entries reserved. + */ void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP free_value); +/** + * Create a new #EdgeHashIterator. The hash table must not be mutated + * while the iterator is in use, and the iterator will step exactly + * #BLI_edgehash_len(eh) times before becoming done. + */ EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +/** + * Initialize an already allocated #EdgeHashIterator. The hash table must not + * be mutated while the iterator is in use, and the iterator will + * step exactly BLI_edgehash_len(eh) times before becoming done. + * + * \param ehi: The #EdgeHashIterator to initialize. + * \param eh: The #EdgeHash to iterate over. + */ void BLI_edgehashIterator_init(EdgeHashIterator *ehi, EdgeHash *eh); +/** + * Free an #EdgeHashIterator. + */ void BLI_edgehashIterator_free(EdgeHashIterator *ehi); BLI_INLINE void BLI_edgehashIterator_step(EdgeHashIterator *ehi) @@ -133,7 +211,17 @@ EdgeSet *BLI_edgeset_new_ex(const char *info, const unsigned int nentries_reserv ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; EdgeSet *BLI_edgeset_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; int BLI_edgeset_len(const EdgeSet *es) ATTR_WARN_UNUSED_RESULT; +/** + * A version of BLI_edgeset_insert which checks first if the key is in the set. + * \returns true if a new key has been added. + * + * \note #EdgeHash has no equivalent to this because typically the value would be different. + */ bool BLI_edgeset_add(EdgeSet *es, unsigned int v0, unsigned int v1); +/** + * Adds the key to the set (no checks for unique keys!). + * Matching #BLI_edgehash_insert + */ void BLI_edgeset_insert(EdgeSet *es, unsigned int v0, unsigned int v1); bool BLI_edgeset_haskey(const EdgeSet *es, unsigned int v0, @@ -141,6 +229,7 @@ bool BLI_edgeset_haskey(const EdgeSet *es, void BLI_edgeset_free(EdgeSet *es); /* rely on inline api for now */ + EdgeSetIterator *BLI_edgesetIterator_new(EdgeSet *es); void BLI_edgesetIterator_free(EdgeSetIterator *esi); diff --git a/source/blender/blenlib/BLI_expr_pylike_eval.h b/source/blender/blenlib/BLI_expr_pylike_eval.h index c074b5d8130..dccb1863b4b 100644 --- a/source/blender/blenlib/BLI_expr_pylike_eval.h +++ b/source/blender/blenlib/BLI_expr_pylike_eval.h @@ -41,13 +41,35 @@ typedef enum eExprPyLike_EvalStatus { EXPR_PYLIKE_FATAL_ERROR, } eExprPyLike_EvalStatus; +/** + * Free the parsed data; NULL argument is ok. + */ void BLI_expr_pylike_free(struct ExprPyLike_Parsed *expr); +/** + * Check if the parsing result is valid for evaluation. + */ bool BLI_expr_pylike_is_valid(struct ExprPyLike_Parsed *expr); +/** + * Check if the parsed expression always evaluates to the same value. + */ bool BLI_expr_pylike_is_constant(struct ExprPyLike_Parsed *expr); +/** + * Check if the parsed expression uses the parameter with the given index. + */ bool BLI_expr_pylike_is_using_param(struct ExprPyLike_Parsed *expr, int index); +/** + * Compile the expression and return the result. + * + * Parse the expression for evaluation later. + * Returns non-NULL even on failure; use is_valid to check. + */ ExprPyLike_Parsed *BLI_expr_pylike_parse(const char *expression, const char **param_names, int param_names_len); +/** + * Evaluate the expression with the given parameters. + * The order and number of parameters must match the names given to parse. + */ eExprPyLike_EvalStatus BLI_expr_pylike_eval(struct ExprPyLike_Parsed *expr, const double *param_values, int param_values_len, diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h index 906a56ce909..932b67866ea 100644 --- a/source/blender/blenlib/BLI_fileops.h +++ b/source/blender/blenlib/BLI_fileops.h @@ -45,19 +45,40 @@ extern "C" { # define PATH_MAX 4096 #endif -/* Common */ +/* -------------------------------------------------------------------- */ +/** \name Common + * \{ */ +/** + * Returns the st_mode from stat-ing the specified path name, or 0 if stat fails + * (most likely doesn't exist or no access). + */ int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BLI_copy(const char *file, const char *to) ATTR_NONNULL(); +/** + * \return zero on success (matching 'rename' behavior). + */ int BLI_rename(const char *from, const char *to) ATTR_NONNULL(); +/** + * Deletes the specified file or directory (depending on dir), optionally + * doing recursive delete of directory contents. + * + * \return zero on success (matching 'remove' behavior). + */ int BLI_delete(const char *file, bool dir, bool recursive) ATTR_NONNULL(); +/** + * Soft deletes the specified file or directory (depending on dir) by moving the files to the + * recycling bin, optionally doing recursive delete of directory contents. + * + * \return zero on success (matching 'remove' behavior). + */ int BLI_delete_soft(const char *file, const char **error_message) ATTR_NONNULL(); #if 0 /* Unused */ int BLI_move(const char *path, const char *to) ATTR_NONNULL(); int BLI_create_symlink(const char *path, const char *to) ATTR_NONNULL(); #endif -/* keep in sync with the definition of struct direntry in BLI_fileops_types.h */ +/* Keep in sync with the definition of struct `direntry` in `BLI_fileops_types.h`. */ #ifdef WIN32 # if defined(_MSC_VER) typedef struct _stat64 BLI_stat_t; @@ -101,40 +122,102 @@ typedef enum eFileAttributes { (FILE_ATTR_ALIAS | FILE_ATTR_REPARSE_POINT | FILE_ATTR_SYMLINK | FILE_ATTR_JUNCTION_POINT | \ FILE_ATTR_MOUNT_POINT | FILE_ATTR_HARDLINK) -/* Directories */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Directories + * \{ */ struct direntry; +/** + * Does the specified path point to a directory? + * \note Would be better in `fileops.c` except that it needs `stat.h` so add here. + */ bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Does the specified path point to a non-directory? + */ bool BLI_is_file(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * \return true on success (i.e. given path now exists on FS), false otherwise. + */ bool BLI_dir_create_recursive(const char *dir) ATTR_NONNULL(); +/** + * Returns the number of free bytes on the volume containing the specified pathname. + * + * \note Not actually used anywhere. + */ double BLI_dir_free_space(const char *dir) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Copies the current working directory into *dir (max size maxncpy), and + * returns a pointer to same. + * + * \note can return NULL when the size is not big enough + */ char *BLI_current_working_dir(char *dir, const size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); eFileAttributes BLI_file_attributes(const char *path); -/* Filelist */ +/** \} */ +/* -------------------------------------------------------------------- */ +/** \name File-List + * \{ */ + +/** + * Scans the contents of the directory named *dirname, and allocates and fills in an + * array of entries describing them in *filelist. + * + * \return The length of filelist array. + */ unsigned int BLI_filelist_dir_contents(const char *dir, struct direntry **r_filelist); +/** + * Deep-duplicate of a single direntry. + */ void BLI_filelist_entry_duplicate(struct direntry *dst, const struct direntry *src); +/** + * Deep-duplicate of a #direntry array including the array itself. + */ void BLI_filelist_duplicate(struct direntry **dest_filelist, struct direntry *const src_filelist, const unsigned int nrentries); +/** + * Frees storage for a single direntry, not the direntry itself. + */ void BLI_filelist_entry_free(struct direntry *entry); +/** + * Frees storage for an array of #direntry, including the array itself. + */ void BLI_filelist_free(struct direntry *filelist, const unsigned int nrentries); +/** + * Convert given entry's size into human-readable strings. + */ void BLI_filelist_entry_size_to_string(const struct stat *st, const uint64_t sz, const bool compact, char r_size[FILELIST_DIRENTRY_SIZE_LEN]); +/** + * Convert given entry's modes into human-readable strings. + */ void BLI_filelist_entry_mode_to_string(const struct stat *st, const bool compact, char r_mode1[FILELIST_DIRENTRY_MODE_LEN], char r_mode2[FILELIST_DIRENTRY_MODE_LEN], char r_mode3[FILELIST_DIRENTRY_MODE_LEN]); +/** + * Convert given entry's owner into human-readable strings. + */ void BLI_filelist_entry_owner_to_string(const struct stat *st, const bool compact, char r_owner[FILELIST_DIRENTRY_OWNER_LEN]); +/** + * Convert given entry's time into human-readable strings. + * + * \param r_is_today: optional, returns true if the date matches today's. + * \param r_is_yesterday: optional, returns true if the date matches yesterday's. + */ void BLI_filelist_entry_datetime_to_string(const struct stat *st, const int64_t ts, const bool compact, @@ -143,14 +226,28 @@ void BLI_filelist_entry_datetime_to_string(const struct stat *st, bool *r_is_today, bool *r_is_yesterday); -/* Files */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Files + * \{ */ FILE *BLI_fopen(const char *filename, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void *BLI_gzopen(const char *filename, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BLI_open(const char *filename, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BLI_access(const char *filename, int mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Returns true if the file with the specified name can be written. + * This implementation uses access(2), which makes the check according + * to the real UID and GID of the process, not its effective UID and GID. + * This shouldn't matter for Blender, which is not going to run privileged anyway. + */ bool BLI_file_is_writable(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Creates the file with nothing in it, or updates its last-modified date if it already exists. + * Returns true if successful (like the unix touch command). + */ bool BLI_file_touch(const char *file) ATTR_NONNULL(); bool BLI_file_alias_target(const char *filepath, char *r_targetpath) ATTR_WARN_UNUSED_RESULT; @@ -165,23 +262,67 @@ size_t BLI_file_unzstd_to_mem_at_pos(void *buf, size_t len, FILE *file, size_t f ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); bool BLI_file_magic_is_zstd(const char header[4]); +/** + * Returns the file size of an opened file descriptor. + */ size_t BLI_file_descriptor_size(int file) ATTR_WARN_UNUSED_RESULT; +/** + * Returns the size of a file. + */ size_t BLI_file_size(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -/* compare if one was last modified before the other */ +/** + * Compare if one was last modified before the other. + * + * \return true when is `file1` older than `file2`. + */ bool BLI_file_older(const char *file1, const char *file2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -/* read ascii file as lines, empty list if reading fails */ +/** + * Reads the contents of a text file. + * + * \return the lines in a linked list (an empty list when file reading fails). + */ struct LinkNode *BLI_file_read_as_lines(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void *BLI_file_read_text_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size); +/** + * Return the text file data with: + + * - Newlines replaced with '\0'. + * - Optionally trim white-space, replacing trailing <space> & <tab> with '\0'. + * + * This is an alternative to using #BLI_file_read_as_lines, + * allowing us to loop over lines without converting it into a linked list + * with individual allocations. + * + * \param trim_trailing_space: Replace trailing spaces & tabs with nil. + * This arguments prevents the caller from counting blank lines (if that's important). + * \param pad_bytes: When this is non-zero, the first byte is set to nil, + * to simplify parsing the file. + * It's recommended to pass in 1, so all text is nil terminated. + * + * Example looping over lines: + * + * \code{.c} + * size_t data_len; + * char *data = BLI_file_read_text_as_mem_with_newline_as_nil(filepath, true, 1, &data_len); + * char *data_end = data + data_len; + * for (char *line = data; line != data_end; line = strlen(line) + 1) { + * printf("line='%s'\n", line); + * } + * \endcode + */ void *BLI_file_read_text_as_mem_with_newline_as_nil(const char *filepath, bool trim_trailing_space, size_t pad_bytes, size_t *r_size); void *BLI_file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size); +/** + * Frees memory from a previous call to #BLI_file_read_as_lines. + */ void BLI_file_free_lines(struct LinkNode *lines); -/* this weirdo pops up in two places ... */ +/* This weirdo pops up in two places. */ #if !defined(WIN32) # ifndef O_BINARY # define O_BINARY 0 @@ -190,6 +331,8 @@ void BLI_file_free_lines(struct LinkNode *lines); void BLI_get_short_name(char short_name[256], const char *filename); #endif +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index a2c5c6349a5..2c03ce22a6b 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -80,47 +80,183 @@ enum { * Defined in `BLI_ghash.c` * \{ */ +/** + * Creates a new, empty GHash. + * + * \param hashfp: Hash callback. + * \param cmpfp: Comparison callback. + * \param info: Identifier string for the GHash. + * \param nentries_reserve: Optionally reserve the number of members that the hash will hold. + * Use this to avoid resizing buckets if the size is known or can be closely approximated. + * \return An empty GHash. + */ GHash *BLI_ghash_new_ex(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +/** + * Wraps #BLI_ghash_new_ex with zero entries reserved. + */ GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +/** + * Copy given GHash. Keys and values are also copied if relevant callback is provided, + * else pointers remain the same. + */ GHash *BLI_ghash_copy(const GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +/** + * Frees the GHash and its members. + * + * \param gh: The GHash to free. + * \param keyfreefp: Optional callback to free the key. + * \param valfreefp: Optional callback to free the value. + */ void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); +/** + * Reserve given amount of entries (resize \a gh accordingly if needed). + */ void BLI_ghash_reserve(GHash *gh, const unsigned int nentries_reserve); +/** + * Insert a key/value pair into the \a gh. + * + * \note Duplicates are not checked, + * the caller is expected to ensure elements are unique unless + * GHASH_FLAG_ALLOW_DUPES flag is set. + */ void BLI_ghash_insert(GHash *gh, void *key, void *val); +/** + * Inserts a new value to a key that may already be in ghash. + * + * Avoids #BLI_ghash_remove, #BLI_ghash_insert calls (double lookups) + * + * \returns true if a new key has been added. + */ bool BLI_ghash_reinsert( GHash *gh, void *key, void *val, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); +/** + * Replaces the key of an item in the \a gh. + * + * Use when a key is re-allocated or its memory location is changed. + * + * \returns The previous key or NULL if not found, the caller may free if it's needed. + */ void *BLI_ghash_replace_key(GHash *gh, void *key); +/** + * Lookup the value of \a key in \a gh. + * + * \param key: The key to lookup. + * \returns the value for \a key or NULL. + * + * \note When NULL is a valid value, use #BLI_ghash_lookup_p to differentiate a missing key + * from a key with a NULL value. (Avoids calling #BLI_ghash_haskey before #BLI_ghash_lookup) + */ void *BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT; +/** + * A version of #BLI_ghash_lookup which accepts a fallback argument. + */ void *BLI_ghash_lookup_default(const GHash *gh, const void *key, void *val_default) ATTR_WARN_UNUSED_RESULT; +/** + * Lookup a pointer to the value of \a key in \a gh. + * + * \param key: The key to lookup. + * \returns the pointer to value for \a key or NULL. + * + * \note This has 2 main benefits over #BLI_ghash_lookup. + * - A NULL return always means that \a key isn't in \a gh. + * - The value can be modified in-place without further function calls (faster). + */ void **BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT; +/** + * Ensure \a key is exists in \a gh. + * + * This handles the common situation where the caller needs ensure a key is added to \a gh, + * constructing a new value in the case the key isn't found. + * Otherwise use the existing value. + * + * Such situations typically incur multiple lookups, however this function + * avoids them by ensuring the key is added, + * returning a pointer to the value so it can be used or initialized by the caller. + * + * \returns true when the value didn't need to be added. + * (when false, the caller _must_ initialize the value). + */ bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT; +/** + * A version of #BLI_ghash_ensure_p that allows caller to re-assign the key. + * Typically used when the key is to be duplicated. + * + * \warning Caller _must_ write to \a r_key when returning false. + */ bool BLI_ghash_ensure_p_ex(GHash *gh, const void *key, void ***r_key, void ***r_val) ATTR_WARN_UNUSED_RESULT; +/** + * Remove \a key from \a gh, or return false if the key wasn't found. + * + * \param key: The key to remove. + * \param keyfreefp: Optional callback to free the key. + * \param valfreefp: Optional callback to free the value. + * \return true if \a key was removed from \a gh. + */ bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); +/** + * Wraps #BLI_ghash_clear_ex with zero entries reserved. + */ void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); +/** + * Reset \a gh clearing all entries. + * + * \param keyfreefp: Optional callback to free the key. + * \param valfreefp: Optional callback to free the value. + * \param nentries_reserve: Optionally reserve the number of members that the hash will hold. + */ void BLI_ghash_clear_ex(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp, const unsigned int nentries_reserve); +/** + * Remove \a key from \a gh, returning the value or NULL if the key wasn't found. + * + * \param key: The key to remove. + * \param keyfreefp: Optional callback to free the key. + * \return the value of \a key int \a gh or NULL. + */ void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp) ATTR_WARN_UNUSED_RESULT; +/** + * \return true if the \a key is in \a gh. + */ bool BLI_ghash_haskey(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT; +/** + * Remove a random entry from \a gh, returning true + * if a key/value pair could be removed, false otherwise. + * + * \param r_key: The removed key. + * \param r_val: The removed value. + * \param state: Used for efficient removal. + * \return true if there was something to pop, false if ghash was already empty. + */ bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * \return size of the GHash. + */ unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT; +/** + * Sets a GHash flag. + */ void BLI_ghash_flag_set(GHash *gh, unsigned int flag); +/** + * Clear a GHash flag. + */ void BLI_ghash_flag_clear(GHash *gh, unsigned int flag); /** \} */ @@ -129,10 +265,36 @@ void BLI_ghash_flag_clear(GHash *gh, unsigned int flag); /** \name GHash Iterator * \{ */ +/** + * Create a new GHashIterator. The hash table must not be mutated + * while the iterator is in use, and the iterator will step exactly + * #BLI_ghash_len(gh) times before becoming done. + * + * \param gh: The GHash to iterate over. + * \return Pointer to a new iterator. + */ GHashIterator *BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +/** + * Init an already allocated GHashIterator. The hash table must not + * be mutated while the iterator is in use, and the iterator will + * step exactly #BLI_ghash_len(gh) times before becoming done. + * + * \param ghi: The GHashIterator to initialize. + * \param gh: The GHash to iterate over. + */ void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh); +/** + * Free a GHashIterator. + * + * \param ghi: The iterator to free. + */ void BLI_ghashIterator_free(GHashIterator *ghi); +/** + * Steps the iterator to the next index. + * + * \param ghi: The iterator. + */ void BLI_ghashIterator_step(GHashIterator *ghi); BLI_INLINE void *BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT; @@ -195,6 +357,10 @@ typedef GHashKeyCopyFP GSetKeyCopyFP; typedef GHashIterState GSetIterState; +/** \name GSet Public API + * + * Use ghash API to give 'set' functionality + * \{ */ GSet *BLI_gset_new_ex(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info, @@ -202,17 +368,55 @@ GSet *BLI_gset_new_ex(GSetHashFP hashfp, GSet *BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +/** + * Copy given GSet. Keys are also copied if callback is provided, else pointers remain the same. + */ GSet *BLI_gset_copy(const GSet *gs, GSetKeyCopyFP keycopyfp) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; unsigned int BLI_gset_len(const GSet *gs) ATTR_WARN_UNUSED_RESULT; void BLI_gset_flag_set(GSet *gs, unsigned int flag); void BLI_gset_flag_clear(GSet *gs, unsigned int flag); void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp); +/** + * Adds the key to the set (no checks for unique keys!). + * Matching #BLI_ghash_insert + */ void BLI_gset_insert(GSet *gs, void *key); +/** + * A version of BLI_gset_insert which checks first if the key is in the set. + * \returns true if a new key has been added. + * + * \note GHash has no equivalent to this because typically the value would be different. + */ bool BLI_gset_add(GSet *gs, void *key); +/** + * Set counterpart to #BLI_ghash_ensure_p_ex. + * similar to BLI_gset_add, except it returns the key pointer. + * + * \warning Caller _must_ write to \a r_key when returning false. + */ bool BLI_gset_ensure_p_ex(GSet *gs, const void *key, void ***r_key); +/** + * Adds the key to the set (duplicates are managed). + * Matching #BLI_ghash_reinsert + * + * \returns true if a new key has been added. + */ bool BLI_gset_reinsert(GSet *gh, void *key, GSetKeyFreeFP keyfreefp); +/** + * Replaces the key to the set if it's found. + * Matching #BLI_ghash_replace_key + * + * \returns The old key or NULL if not found. + */ void *BLI_gset_replace_key(GSet *gs, void *key); bool BLI_gset_haskey(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT; +/** + * Remove a random entry from \a gs, returning true if a key could be removed, false otherwise. + * + * \param r_key: The removed key. + * \param state: Used for efficient removal. + * \return true if there was something to pop, false if gset was already empty. + */ bool BLI_gset_pop(GSet *gs, GSetIterState *state, void **r_key) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); bool BLI_gset_remove(GSet *gs, const void *key, GSetKeyFreeFP keyfreefp); @@ -220,7 +424,14 @@ void BLI_gset_clear_ex(GSet *gs, GSetKeyFreeFP keyfreefp, const unsigned int nen void BLI_gset_clear(GSet *gs, GSetKeyFreeFP keyfreefp); /* When set's are used for key & value. */ +/** + * Returns the pointer to the key if it's found. + */ void *BLI_gset_lookup(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT; +/** + * Returns the pointer to the key if it's found, removing it from the GSet. + * \note Caller must handle freeing. + */ void *BLI_gset_pop_key(GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT; /** \} */ @@ -282,9 +493,19 @@ BLI_INLINE bool BLI_gsetIterator_done(const GSetIterator *gsi) /* For testing, debugging only */ #ifdef GHASH_INTERNAL_API +/** + * \return number of buckets in the GHash. + */ int BLI_ghash_buckets_len(const GHash *gh); int BLI_gset_buckets_len(const GSet *gs); +/** + * Measure how well the hash function performs (1.0 is approx as good as random distribution), + * and return a few other stats like load, + * variance of the distribution of the entries in the buckets, etc. + * + * Smaller is better! + */ double BLI_ghash_calc_quality_ex(GHash *gh, double *r_load, double *r_variance, @@ -346,6 +567,15 @@ double BLI_gset_calc_quality(GSet *gs); unsigned int BLI_ghashutil_ptrhash(const void *key); bool BLI_ghashutil_ptrcmp(const void *a, const void *b); +/** + * This function implements the widely used "djb" hash apparently posted + * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit + * unsigned hash value starts at 5381 and for each byte 'c' in the + * string, is updated: `hash = hash * 33 + c`. + * This function uses the signed value of each byte. + * + * NOTE: this is the same hash method that glib 2.34.0 uses. + */ unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n); #define BLI_ghashutil_strhash(key) \ (CHECK_TYPE_ANY(key, char *, const char *, const char *const), BLI_ghashutil_strhash_p(key)) diff --git a/source/blender/blenlib/BLI_gsqueue.h b/source/blender/blenlib/BLI_gsqueue.h index 9cc61bc8059..8b32c09b56b 100644 --- a/source/blender/blenlib/BLI_gsqueue.h +++ b/source/blender/blenlib/BLI_gsqueue.h @@ -32,10 +32,30 @@ extern "C" { typedef struct _GSQueue GSQueue; GSQueue *BLI_gsqueue_new(const size_t elem_size); +/** + * Returns true if the queue is empty, false otherwise. + */ bool BLI_gsqueue_is_empty(const GSQueue *queue); size_t BLI_gsqueue_len(const GSQueue *queue); +/** + * Retrieves and removes the first element from the queue. + * The value is copies to \a r_item, which must be at least \a elem_size bytes. + * + * Does not reduce amount of allocated memory. + */ void BLI_gsqueue_pop(GSQueue *queue, void *r_item); +/** + * Copies the source value onto the end of the queue + * + * \note This copies #GSQueue.elem_size bytes from \a item, + * (the pointer itself is not stored). + * + * \param item: source data to be copied to the queue. + */ void BLI_gsqueue_push(GSQueue *queue, const void *item); +/** + * Free the queue's data and the queue itself. + */ void BLI_gsqueue_free(GSQueue *queue); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_hash_md5.h b/source/blender/blenlib/BLI_hash_md5.h index 227cfcc8876..7b5868d7ffc 100644 --- a/source/blender/blenlib/BLI_hash_md5.h +++ b/source/blender/blenlib/BLI_hash_md5.h @@ -24,17 +24,18 @@ extern "C" { #endif -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - * result is always in little endian byte order, so that a byte-wise - * output yields to the wanted ASCII representation of the message - * digest. */ - +/** + * Compute MD5 message digest for 'len' bytes beginning at 'buffer'. + * The result is always in little endian byte order, + * so that a byte-wise output yields to the wanted ASCII representation of the message digest. + */ void *BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock); -/* Compute MD5 message digest for bytes read from STREAM. The - * resulting message digest number will be written into the 16 bytes - * beginning at RESBLOCK. */ - +/** + * Compute MD5 message digest for bytes read from 'stream'. + * The resulting message digest number will be written into the 16 bytes beginning at 'resblock'. + * \return Non-zero if an error occurred. + */ int BLI_hash_md5_stream(FILE *stream, void *resblock); char *BLI_hash_md5_to_hexdigest(void *resblock, char r_hex_digest[33]); diff --git a/source/blender/blenlib/BLI_hash_mm2a.h b/source/blender/blenlib/BLI_hash_mm2a.h index 193a78e6293..2619e516861 100644 --- a/source/blender/blenlib/BLI_hash_mm2a.h +++ b/source/blender/blenlib/BLI_hash_mm2a.h @@ -41,6 +41,9 @@ void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data); uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2); +/** + * Non-incremental version, quicker for small keys. + */ uint32_t BLI_hash_mm2(const unsigned char *data, size_t len, uint32_t seed); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h index 4cfb7945303..b6a12521fff 100644 --- a/source/blender/blenlib/BLI_heap.h +++ b/source/blender/blenlib/BLI_heap.h @@ -34,27 +34,59 @@ typedef struct HeapNode HeapNode; typedef void (*HeapFreeFP)(void *ptr); +/** + * Creates a new heap. Removed nodes are recycled, so memory usage will not shrink. + * + * \note Use when the size of the heap is known in advance. + */ Heap *BLI_heap_new_ex(unsigned int tot_reserve) ATTR_WARN_UNUSED_RESULT; Heap *BLI_heap_new(void) ATTR_WARN_UNUSED_RESULT; void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1); void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1); +/** + * Insert heap node with a value (often a 'cost') and pointer into the heap, + * duplicate values are allowed. + */ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) ATTR_NONNULL(1); +/** + * Convenience function since this is a common pattern. + */ void BLI_heap_insert_or_update(Heap *heap, HeapNode **node_p, float value, void *ptr) ATTR_NONNULL(1, 2); void BLI_heap_remove(Heap *heap, HeapNode *node) ATTR_NONNULL(1, 2); bool BLI_heap_is_empty(const Heap *heap) ATTR_NONNULL(1); unsigned int BLI_heap_len(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Return the top node of the heap. + * This is the node with the lowest value. + */ HeapNode *BLI_heap_top(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Return the value of top node of the heap. + * This is the node with the lowest value. + */ float BLI_heap_top_value(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Pop the top node off the heap and return its pointer. + */ void *BLI_heap_pop_min(Heap *heap) ATTR_NONNULL(1); +/** + * Can be used to avoid #BLI_heap_remove, #BLI_heap_insert calls, + * balancing the tree still has a performance cost, + * but is often much less than remove/insert, difference is most noticeable with large heaps. + */ void BLI_heap_node_value_update(Heap *heap, HeapNode *node, float value) ATTR_NONNULL(1, 2); void BLI_heap_node_value_update_ptr(Heap *heap, HeapNode *node, float value, void *ptr) ATTR_NONNULL(1, 2); -/* Return the value or pointer of a heap node. */ +/** + * Return the value or pointer of a heap node. + */ float BLI_heap_node_value(const HeapNode *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); void *BLI_heap_node_ptr(const HeapNode *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); -/* only for gtest */ +/** + * Only for checking internal errors (gtest). + */ bool BLI_heap_is_valid(const Heap *heap); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_heap_simple.h b/source/blender/blenlib/BLI_heap_simple.h index b2a1b5582e5..5583f209de0 100644 --- a/source/blender/blenlib/BLI_heap_simple.h +++ b/source/blender/blenlib/BLI_heap_simple.h @@ -30,14 +30,29 @@ typedef struct HeapSimple HeapSimple; typedef void (*HeapSimpleFreeFP)(void *ptr); +/** + * Creates a new simple heap, which only supports insertion and removal from top. + * + * \note Use when the size of the heap is known in advance. + */ HeapSimple *BLI_heapsimple_new_ex(unsigned int tot_reserve) ATTR_WARN_UNUSED_RESULT; HeapSimple *BLI_heapsimple_new(void) ATTR_WARN_UNUSED_RESULT; void BLI_heapsimple_clear(HeapSimple *heap, HeapSimpleFreeFP ptrfreefp) ATTR_NONNULL(1); void BLI_heapsimple_free(HeapSimple *heap, HeapSimpleFreeFP ptrfreefp) ATTR_NONNULL(1); +/** + * Insert heap node with a value (often a 'cost') and pointer into the heap, + * duplicate values are allowed. + */ void BLI_heapsimple_insert(HeapSimple *heap, float value, void *ptr) ATTR_NONNULL(1); bool BLI_heapsimple_is_empty(const HeapSimple *heap) ATTR_NONNULL(1); uint BLI_heapsimple_len(const HeapSimple *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Return the lowest value of the heap. + */ float BLI_heapsimple_top_value(const HeapSimple *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Pop the top node off the heap and return its pointer. + */ void *BLI_heapsimple_pop_min(HeapSimple *heap) ATTR_NONNULL(1); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_index_mask.hh b/source/blender/blenlib/BLI_index_mask.hh index 16bb8c931cc..2dca3689cb1 100644 --- a/source/blender/blenlib/BLI_index_mask.hh +++ b/source/blender/blenlib/BLI_index_mask.hh @@ -45,11 +45,11 @@ namespace blender { class IndexMask { private: - /* The underlying reference to sorted integers. */ + /** The underlying reference to sorted integers. */ Span<int64_t> indices_; public: - /* Creates an IndexMask that contains no indices. */ + /** Creates an IndexMask that contains no indices. */ IndexMask() = default; /** @@ -224,6 +224,24 @@ class IndexMask { } IndexMask slice(IndexRange slice) const; + /** + * Create a sub-mask that is also shifted to the beginning. + * The shifting to the beginning allows code to work with smaller indices, + * which is more memory efficient. + * + * \return New index mask with the size of #slice. It is either empty or starts with 0. + * It might reference indices that have been appended to #r_new_indices. + * + * Example: + * \code{.unparsed} + * this: [2, 3, 5, 7, 8, 9, 10] + * slice: ^--------^ + * output: [0, 2, 4, 5] + * \endcode + * + * All the indices in the sub-mask are shifted by 3 towards zero, + * so that the first index in the output is zero. + */ IndexMask slice_and_offset(IndexRange slice, Vector<int64_t> &r_new_indices) const; }; diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 5e0ea4f2a99..2f41be369c1 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -104,25 +104,35 @@ enum { #define BVH_RAYCAST_DEFAULT (BVH_RAYCAST_WATERTIGHT) #define BVH_RAYCAST_DIST_MAX (FLT_MAX / 2.0f) -/* callback must update nearest in case it finds a nearest result */ +/** + * Callback must update nearest in case it finds a nearest result. + */ typedef void (*BVHTree_NearestPointCallback)(void *userdata, int index, const float co[3], BVHTreeNearest *nearest); -/* callback must update hit in case it finds a nearest successful hit */ +/** + * Callback must update hit in case it finds a nearest successful hit. + */ typedef void (*BVHTree_RayCastCallback)(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit); -/* callback to check if 2 nodes overlap (use thread if intersection results need to be stored) */ +/** + * Callback to check if 2 nodes overlap (use thread if intersection results need to be stored). + */ typedef bool (*BVHTree_OverlapCallback)(void *userdata, int index_a, int index_b, int thread); -/* callback to range search query */ +/** + * Callback to range search query. + */ typedef void (*BVHTree_RangeQuery)(void *userdata, int index, const float co[3], float dist_sq); -/* callback to find nearest projected */ +/** + * Callback to find nearest projected. + */ typedef void (*BVHTree_NearestProjectedCallback)(void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, @@ -131,42 +141,67 @@ typedef void (*BVHTree_NearestProjectedCallback)(void *userdata, BVHTreeNearest *nearest); /* callbacks to BLI_bvhtree_walk_dfs */ -/* return true to traverse into this nodes children, else skip. */ + +/** + * Return true to traverse into this nodes children, else skip. + */ typedef bool (*BVHTree_WalkParentCallback)(const BVHTreeAxisRange *bounds, void *userdata); -/* return true to keep walking, else early-exit the search. */ +/** + * Return true to keep walking, else early-exit the search. + */ typedef bool (*BVHTree_WalkLeafCallback)(const BVHTreeAxisRange *bounds, int index, void *userdata); -/* return true to search (min, max) else (max, min). */ +/** + * Return true to search (min, max) else (max, min). + */ typedef bool (*BVHTree_WalkOrderCallback)(const BVHTreeAxisRange *bounds, char axis, void *userdata); +/** + * \note many callers don't check for `NULL` return. + */ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis); void BLI_bvhtree_free(BVHTree *tree); -/* construct: first insert points, then call balance */ +/** + * Construct: first insert points, then call balance. + */ void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints); void BLI_bvhtree_balance(BVHTree *tree); -/* update: first update points/nodes, then call update_tree to refit the bounding volumes */ +/** + * Update: first update points/nodes, then call update_tree to refit the bounding volumes. + * \note call before #BLI_bvhtree_update_tree(). + */ bool BLI_bvhtree_update_node( BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints); +/** + * Call #BLI_bvhtree_update_node() first for every node/point/triangle. + */ void BLI_bvhtree_update_tree(BVHTree *tree); +/** + * Use to check the total number of threads #BLI_bvhtree_overlap will use. + * + * \warning Must be the first tree passed to #BLI_bvhtree_overlap! + */ int BLI_bvhtree_overlap_thread_num(const BVHTree *tree); -/* collision/overlap: check two trees if they overlap, - * alloc's *overlap with length of the int return value */ -BVHTreeOverlap *BLI_bvhtree_overlap_ex( - const BVHTree *tree1, - const BVHTree *tree2, - uint *r_overlap_tot, - /* optional callback to test the overlap before adding (must be thread-safe!) */ - BVHTree_OverlapCallback callback, - void *userdata, - const uint max_interactions, - const int flag); +/** + * Collision/overlap: check two trees if they overlap, + * alloc's *overlap with length of the int return value. + * + * \param callback: optional, to test the overlap before adding (must be thread-safe!). + */ +BVHTreeOverlap *BLI_bvhtree_overlap_ex(const BVHTree *tree1, + const BVHTree *tree2, + uint *r_overlap_tot, + BVHTree_OverlapCallback callback, + void *userdata, + const uint max_interactions, + const int flag); BVHTreeOverlap *BLI_bvhtree_overlap(const BVHTree *tree1, const BVHTree *tree2, unsigned int *r_overlap_tot, @@ -175,14 +210,26 @@ BVHTreeOverlap *BLI_bvhtree_overlap(const BVHTree *tree1, int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_tot); +/** + * Number of times #BLI_bvhtree_insert has been called. + * mainly useful for asserts functions to check we added the correct number. + */ int BLI_bvhtree_get_len(const BVHTree *tree); +/** + * Maximum number of children that a node can have. + */ int BLI_bvhtree_get_tree_type(const BVHTree *tree); float BLI_bvhtree_get_epsilon(const BVHTree *tree); +/** + * This function returns the bounding box of the BVH tree. + */ void BLI_bvhtree_get_bounding_box(BVHTree *tree, float r_bb_min[3], float r_bb_max[3]); -/* find nearest node to the given coordinates +/** + * Find nearest node to the given coordinates * (if nearest is given it will only search nodes where - * square distance is smaller than nearest->dist) */ + * square distance is smaller than nearest->dist). + */ int BLI_bvhtree_find_nearest_ex(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, @@ -195,6 +242,10 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, BVHTree_NearestPointCallback callback, void *userdata); +/** + * Find the first node nearby. + * Favors speed over quality since it doesn't find the best target node. + */ int BLI_bvhtree_find_nearest_first(BVHTree *tree, const float co[3], const float dist_sq, @@ -217,6 +268,15 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, BVHTree_RayCastCallback callback, void *userdata); +/** + * Calls the callback for every ray intersection + * + * \note Using a \a callback which resets or never sets the #BVHTreeRayHit index & dist works too, + * however using this function means existing generic callbacks can be used from custom callbacks + * without having to handle resetting the hit beforehand. + * It also avoid redundant argument and return value which aren't meaningful + * when collecting multiple hits. + */ void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree, const float co[3], const float dir[3], @@ -238,7 +298,9 @@ float BLI_bvhtree_bb_raycast(const float bv[6], const float light_end[3], float pos[3]); -/* range query */ +/** + * Range query. + */ int BLI_bvhtree_range_query( BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata); @@ -252,13 +314,27 @@ int BLI_bvhtree_find_nearest_projected(BVHTree *tree, BVHTree_NearestProjectedCallback callback, void *userdata); +/** + * This is a generic function to perform a depth first search on the #BVHTree + * where the search order and nodes traversed depend on callbacks passed in. + * + * \param tree: Tree to walk. + * \param walk_parent_cb: Callback on a parents bound-box to test if it should be traversed. + * \param walk_leaf_cb: Callback to test leaf nodes, callback must store its own result, + * returning false exits early. + * \param walk_order_cb: Callback that indicates which direction to search, + * either from the node with the lower or higher K-DOP axis value. + * \param userdata: Argument passed to all callbacks. + */ void BLI_bvhtree_walk_dfs(BVHTree *tree, BVHTree_WalkParentCallback walk_parent_cb, BVHTree_WalkLeafCallback walk_leaf_cb, BVHTree_WalkOrderCallback walk_order_cb, void *userdata); -/* expose for bvh callbacks to use */ +/** + * Expose for BVH callbacks to use. + */ extern const float bvhtree_kdop_axes[13][3]; #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_lasso_2d.h b/source/blender/blenlib/BLI_lasso_2d.h index e920d1189a2..5f034bfdc1d 100644 --- a/source/blender/blenlib/BLI_lasso_2d.h +++ b/source/blender/blenlib/BLI_lasso_2d.h @@ -35,6 +35,9 @@ bool BLI_lasso_is_point_inside(const int mcoords[][2], const int sx, const int sy, const int error_value); +/** + * Edge version for lasso select. We assume bound-box check was done. + */ bool BLI_lasso_is_edge_inside(const int mcoords[][2], const unsigned int mcoords_len, int x0, diff --git a/source/blender/blenlib/BLI_linklist.h b/source/blender/blenlib/BLI_linklist.h index 25d58a3050c..d872921defc 100644 --- a/source/blender/blenlib/BLI_linklist.h +++ b/source/blender/blenlib/BLI_linklist.h @@ -58,8 +58,15 @@ LinkNode *BLI_linklist_find_last(LinkNode *list) ATTR_WARN_UNUSED_RESULT; void BLI_linklist_reverse(LinkNode **listp) ATTR_NONNULL(1); +/** + * Move an item from its current position to a new one inside a single-linked list. + * \note `*listp` may be modified. + */ void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index) ATTR_NONNULL(1); +/** + * A version of #BLI_linklist_prepend that takes the allocated link. + */ void BLI_linklist_prepend_nlink(LinkNode **listp, void *ptr, LinkNode *nlink) ATTR_NONNULL(1, 3); void BLI_linklist_prepend(LinkNode **listp, void *ptr) ATTR_NONNULL(1); void BLI_linklist_prepend_arena(LinkNode **listp, void *ptr, struct MemArena *ma) @@ -67,7 +74,11 @@ void BLI_linklist_prepend_arena(LinkNode **listp, void *ptr, struct MemArena *ma void BLI_linklist_prepend_pool(LinkNode **listp, void *ptr, struct BLI_mempool *mempool) ATTR_NONNULL(1, 3); -/* use LinkNodePair to avoid full search */ +/* Use #LinkNodePair to avoid full search. */ + +/** + * A version of append that takes the allocated link. + */ void BLI_linklist_append_nlink(LinkNodePair *list_pair, void *ptr, LinkNode *nlink) ATTR_NONNULL(1, 3); void BLI_linklist_append(LinkNodePair *list_pair, void *ptr) ATTR_NONNULL(1); diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index cf525d1c2af..7d808d339e9 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -33,89 +33,233 @@ extern "C" { #endif +/** + * Returns the position of \a vlink within \a listbase, numbering from 0, or -1 if not found. + */ int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Returns the 0-based index of the first element of listbase which contains the specified + * null-terminated string at the specified offset, or -1 if not found. + */ int BLI_findstringindex(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); -/* find forwards */ +/* Find forwards. */ + +/** + * Returns the nth element of \a listbase, numbering from 0. + */ void *BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Finds the first element of \a listbase which contains the null-terminated + * string \a id at the specified offset, returning NULL if not found. + */ void *BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Finds the first element of \a listbase which contains a pointer to the + * null-terminated string \a id at the specified offset, returning NULL if not found. + */ void *BLI_findstring_ptr(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Finds the first element of listbase which contains the specified pointer value + * at the specified offset, returning NULL if not found. + */ void *BLI_findptr(const struct ListBase *listbase, const void *ptr, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Finds the first element of listbase which contains the specified bytes + * at the specified offset, returning NULL if not found. + */ void *BLI_listbase_bytes_find(const ListBase *listbase, const void *bytes, const size_t bytes_size, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2); +/** + * Find the first item in the list that matches the given string, or the given index as fallback. + * + * \note The string is only used is non-NULL and non-empty. + * + * \return The found item, or NULL. + */ void *BLI_listbase_string_or_index_find(const struct ListBase *listbase, const char *string, const size_t string_offset, const int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); -/* find backwards */ +/* Find backwards. */ + +/** + * Returns the nth-last element of \a listbase, numbering from 0. + */ void *BLI_rfindlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Finds the last element of \a listbase which contains the + * null-terminated string \a id at the specified offset, returning NULL if not found. + */ void *BLI_rfindstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Finds the last element of \a listbase which contains a pointer to the + * null-terminated string \a id at the specified offset, returning NULL if not found. + */ void *BLI_rfindstring_ptr(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Finds the last element of listbase which contains the specified pointer value + * at the specified offset, returning NULL if not found. + */ void *BLI_rfindptr(const struct ListBase *listbase, const void *ptr, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Finds the last element of listbase which contains the specified bytes + * at the specified offset, returning NULL if not found. + */ void *BLI_listbase_bytes_rfind(const ListBase *listbase, const void *bytes, const size_t bytes_size, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2); +/** + * Removes and disposes of the entire contents of \a listbase using guardedalloc. + */ void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1); +/** + * Appends \a vlink (assumed to begin with a Link) onto listbase. + */ void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); +/** + * Removes \a vlink from \a listbase. Assumes it is linked into there! + */ void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); +/** + * Checks that \a vlink is linked into listbase, removing it from there if so. + */ bool BLI_remlink_safe(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); +/** + * Removes the head from \a listbase and returns it. + */ void *BLI_pophead(ListBase *listbase) ATTR_NONNULL(1); +/** + * Removes the tail from \a listbase and returns it. + */ void *BLI_poptail(ListBase *listbase) ATTR_NONNULL(1); +/** + * Prepends \a vlink (assumed to begin with a Link) onto listbase. + */ void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); +/** + * Inserts \a vnewlink immediately preceding \a vnextlink in listbase. + * Or, if \a vnextlink is NULL, puts \a vnewlink at the end of the list. + */ void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1); +/** + * Inserts \a vnewlink immediately following \a vprevlink in \a listbase. + * Or, if \a vprevlink is NULL, puts \a vnewlink at the front of the list. + */ void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1); +/** + * Insert a link in place of another, without changing its position in the list. + * + * Puts `vnewlink` in the position of `vreplacelink`, removing `vreplacelink`. + * - `vreplacelink` *must* be in the list. + * - `vnewlink` *must not* be in the list. + */ void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink) ATTR_NONNULL(1, 2, 3); +/** + * Sorts the elements of listbase into the order defined by cmp + * (which should return 1 if its first arg should come after its second arg). + * This uses insertion sort, so NOT ok for large list. + */ void BLI_listbase_sort(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2); void BLI_listbase_sort_r(ListBase *listbase, int (*cmp)(void *, const void *, const void *), void *thunk) ATTR_NONNULL(1, 2); +/** + * Reinsert \a vlink relative to its current position but offset by \a step. Doesn't move + * item if new position would exceed list (could optionally move to head/tail). + * + * \param step: Absolute value defines step size, sign defines direction. E.g pass -1 + * to move \a vlink before previous, or 1 to move behind next. + * \return If position of \a vlink has changed. + */ bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL(); +/** + * Move the link at the index \a from to the position at index \a to. + * + * \return If the move was successful. + */ bool BLI_listbase_move_index(ListBase *listbase, int from, int to) ATTR_NONNULL(); +/** + * Removes and disposes of the entire contents of listbase using direct free(3). + */ void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1); +/** + * Returns the number of elements in \a listbase, up until (and including count_max) + * + * \note Use to avoid redundant looping. + */ int BLI_listbase_count_at_most(const struct ListBase *listbase, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Returns the number of elements in \a listbase. + */ int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Removes \a vlink from listbase and disposes of it. Assumes it is linked into there! + */ void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); +/** + * Swaps \a vlinka and \a vlinkb in the list. Assumes they are both already in the list! + */ void BLI_listbase_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2); +/** + * Swaps \a vlinka and \a vlinkb from their respective lists. + * Assumes they are both already in their \a listbasea! + */ void BLI_listbases_swaplinks(struct ListBase *listbasea, struct ListBase *listbaseb, void *vlinka, void *vlinkb) ATTR_NONNULL(2, 3); +/** + * Moves the entire contents of \a src onto the end of \a dst. + */ void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1, 2); +/** + * Moves the entire contents of \a src at the beginning of \a dst. + */ void BLI_movelisttolist_reverse(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1, 2); +/** + * Sets dst to a duplicate of the entire contents of src. dst may be the same as src. + */ void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1, 2); void BLI_listbase_reverse(struct ListBase *lb) ATTR_NONNULL(1); +/** + * \param vlink: Link to make first. + */ void BLI_listbase_rotate_first(struct ListBase *lb, void *vlink) ATTR_NONNULL(1, 2); +/** + * \param vlink: Link to make last. + */ void BLI_listbase_rotate_last(struct ListBase *lb, void *vlink) ATTR_NONNULL(1, 2); /** @@ -134,7 +278,9 @@ BLI_INLINE void BLI_listbase_clear(struct ListBase *lb) lb->first = lb->last = (void *)0; } -/* create a generic list node containing link to provided data */ +/** + * Create a generic list node containing link to provided data. + */ struct LinkData *BLI_genericNodeN(void *data); /** @@ -188,13 +334,17 @@ struct LinkData *BLI_genericNodeN(void *data); #define LISTBASE_FOREACH_BACKWARD(type, var, list) \ for (type var = (type)((list)->last); var != NULL; var = (type)(((Link *)(var))->prev)) -/** A version of #LISTBASE_FOREACH that supports removing the item we're looping over. */ +/** + * A version of #LISTBASE_FOREACH that supports removing the item we're looping over. + */ #define LISTBASE_FOREACH_MUTABLE(type, var, list) \ for (type var = (type)((list)->first), *var##_iter_next; \ ((var != NULL) ? ((void)(var##_iter_next = (type)(((Link *)(var))->next)), 1) : 0); \ var = var##_iter_next) -/** A version of #LISTBASE_FOREACH_BACKWARD that supports removing the item we're looping over. */ +/** + * A version of #LISTBASE_FOREACH_BACKWARD that supports removing the item we're looping over. + */ #define LISTBASE_FOREACH_BACKWARD_MUTABLE(type, var, list) \ for (type var = (type)((list)->last), *var##_iter_prev; \ ((var != NULL) ? ((void)(var##_iter_prev = (type)(((Link *)(var))->prev)), 1) : 0); \ diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 9b54f780296..83822481112 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -97,6 +97,7 @@ extern "C" { /******************************* Float ******************************/ +/* powf is really slow for raising to integer powers. */ MINLINE float pow2f(float x); MINLINE float pow3f(float x); MINLINE float pow4f(float x); @@ -120,11 +121,18 @@ MINLINE double interpd(double a, double b, double t); MINLINE float ratiof(float min, float max, float pos); MINLINE double ratiod(double min, double max, double pos); +/** + * Map a normalized value, i.e. from interval [0, 1] to interval [a, b]. + */ MINLINE float scalenorm(float a, float b, float x); +/** + * Map a normalized value, i.e. from interval [0, 1] to interval [a, b]. + */ MINLINE double scalenormd(double a, double b, double x); /* NOTE: Compilers will upcast all types smaller than int to int when performing arithmetic * operation. */ + MINLINE int square_s(short a); MINLINE int square_uchar(unsigned char a); MINLINE int cube_s(short a); @@ -170,7 +178,23 @@ MINLINE int clamp_i(int value, int min, int max); MINLINE float clamp_f(float value, float min, float max); MINLINE size_t clamp_z(size_t value, size_t min, size_t max); +/** + * Almost-equal for IEEE floats, using absolute difference method. + * + * \param max_diff: the maximum absolute difference. + */ MINLINE int compare_ff(float a, float b, const float max_diff); +/** + * Almost-equal for IEEE floats, using their integer representation + * (mixing ULP and absolute difference methods). + * + * \param max_diff: is the maximum absolute difference (allows to take care of the near-zero area, + * where relative difference methods cannot really work). + * \param max_ulps: is the 'maximum number of floats + 1' + * allowed between \a a and \a b to consider them equal. + * + * \see https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ + */ MINLINE int compare_ff_relative(float a, float b, const float max_diff, const int max_ulps); MINLINE bool compare_threshold_relative(const float value1, const float value2, @@ -180,13 +204,25 @@ MINLINE float signf(float f); MINLINE int signum_i_ex(float a, float eps); MINLINE int signum_i(float a); +/** + * Used for zoom values. + */ MINLINE float power_of_2(float f); +/** + * Returns number of (base ten) *significant* digits of integer part of given float + * (negative in case of decimal-only floats, 0.01 returns -1 e.g.). + */ MINLINE int integer_digits_f(const float f); +/** + * Returns number of (base ten) *significant* digits of integer part of given double + * (negative in case of decimal-only floats, 0.01 returns -1 e.g.). + */ MINLINE int integer_digits_d(const double d); MINLINE int integer_digits_i(const int i); -/* these don't really fit anywhere but were being copied about a lot */ +/* These don't really fit anywhere but were being copied about a lot. */ + MINLINE int is_power_of_2_i(int n); MINLINE int power_of_2_max_i(int n); MINLINE int power_of_2_min_i(int n); @@ -196,9 +232,19 @@ MINLINE unsigned int power_of_2_min_u(unsigned int x); MINLINE unsigned int log2_floor_u(unsigned int x); MINLINE unsigned int log2_ceil_u(unsigned int x); +/** + * Integer division that rounds 0.5 up, particularly useful for color blending + * with integers, to avoid gradual darkening when rounding down. + */ MINLINE int divide_round_i(int a, int b); +/** + * modulo that handles negative numbers, works the same as Python's. + */ MINLINE int mod_i(int i, int n); +/** + * Round to closest even number, halfway cases are rounded away from zero. + */ MINLINE float round_to_even(float f); MINLINE signed char round_fl_to_char(float a); @@ -230,18 +276,40 @@ MINLINE int round_db_to_int_clamp(double a); MINLINE unsigned int round_db_to_uint_clamp(double a); int pow_i(int base, int exp); + +/** + * \param ndigits: must be between 0 and 21. + */ double double_round(double x, int ndigits); +/** + * Floor to the nearest power of 10, e.g.: + * - 15.0 -> 10.0 + * - 0.015 -> 0.01 + * - 1.0 -> 1.0 + * + * \param f: Value to floor, must be over 0.0. + * \note If we wanted to support signed values we could if this becomes necessary. + */ float floor_power_of_10(float f); +/** + * Ceiling to the nearest power of 10, e.g.: + * - 15.0 -> 100.0 + * - 0.015 -> 0.1 + * - 1.0 -> 1.0 + * + * \param f: Value to ceiling, must be over 0.0. + * \note If we wanted to support signed values we could if this becomes necessary. + */ float ceil_power_of_10(float f); #ifdef BLI_MATH_GCC_WARN_PRAGMA # pragma GCC diagnostic pop #endif -/* asserts, some math functions expect normalized inputs - * check the vector is unit length, or zero length (which can't be helped in some cases). - */ +/* Asserts, some math functions expect normalized inputs + * check the vector is unit length, or zero length (which can't be helped in some cases). */ + #ifndef NDEBUG /** \note 0.0001 is too small because normals may be converted from short's: see T34322. */ # define BLI_ASSERT_UNIT_EPSILON 0.0002f diff --git a/source/blender/blenlib/BLI_math_boolean.hh b/source/blender/blenlib/BLI_math_boolean.hh index 79b1483bfb8..20fd00b2aa4 100644 --- a/source/blender/blenlib/BLI_math_boolean.hh +++ b/source/blender/blenlib/BLI_math_boolean.hh @@ -32,20 +32,24 @@ namespace blender { -/* #orient2d gives the exact result, using multi-precision arithmetic when result +/** + * #orient2d gives the exact result, using multi-precision arithmetic when result * is close to zero. orient3d_fast just uses double arithmetic, so may be * wrong if the answer is very close to zero. - * Similarly, for #incircle and #incircle_fast. */ + * Similarly, for #incircle and #incircle_fast. + */ int orient2d(const double2 &a, const double2 &b, const double2 &c); int orient2d_fast(const double2 &a, const double2 &b, const double2 &c); int incircle(const double2 &a, const double2 &b, const double2 &c, const double2 &d); int incircle_fast(const double2 &a, const double2 &b, const double2 &c, const double2 &d); -/* #orient3d gives the exact result, using multi-precision arithmetic when result +/** + * #orient3d gives the exact result, using multi-precision arithmetic when result * is close to zero. orient3d_fast just uses double arithmetic, so may be * wrong if the answer is very close to zero. - * Similarly, for #insphere and #insphere_fast. */ + * Similarly, for #insphere and #insphere_fast. + */ int orient3d(const double3 &a, const double3 &b, const double3 &c, const double3 &d); int orient3d_fast(const double3 &a, const double3 &b, const double3 &c, const double3 &d); @@ -55,8 +59,23 @@ int insphere_fast( const double3 &a, const double3 &b, const double3 &c, const double3 &d, const double3 &e); #ifdef WITH_GMP +/** + * Return +1 if a, b, c are in CCW order around a circle in the plane. + * Return -1 if they are in CW order, and 0 if they are in line. + */ int orient2d(const mpq2 &a, const mpq2 &b, const mpq2 &c); +/** + * Return +1 if d is in the oriented circle through a, b, and c. + * The oriented circle goes CCW through a, b, and c. + * Return -1 if d is outside, and 0 if it is on the circle. + */ int incircle(const mpq2 &a, const mpq2 &b, const mpq2 &c, const mpq2 &d); +/** + * Return +1 if d is below the plane containing a, b, c (which appear + * CCW when viewed from above the plane). + * Return -1 if d is above the plane. + * Return 0 if it is on the plane. + */ int orient3d(const mpq3 &a, const mpq3 &b, const mpq3 &c, const mpq3 &d); #endif } // namespace blender diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index 28257ba418a..32424f37676 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -31,6 +31,10 @@ extern "C" { #endif +/* -------------------------------------------------------------------- */ +/** \name Defines + * \{ */ + /* YCbCr */ #define BLI_YCC_ITU_BT601 0 #define BLI_YCC_ITU_BT709 1 @@ -40,7 +44,11 @@ extern "C" { #define BLI_YUV_ITU_BT601 0 #define BLI_YUV_ITU_BT709 1 -/******************* Conversion to RGB ********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Conversion to RGB + * \{ */ void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b); void hsv_to_rgb_v(const float hsv[3], float r_rgb[3]); @@ -51,9 +59,18 @@ void yuv_to_rgb(float y, float u, float v, float *r_r, float *r_g, float *r_b, i void ycc_to_rgb(float y, float cb, float cr, float *r_r, float *r_g, float *r_b, int colorspace); void cpack_to_rgb(unsigned int col, float *r_r, float *r_g, float *r_b); -/***************** Conversion from RGB ********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Conversion from RGB + * \{ */ void rgb_to_yuv(float r, float g, float b, float *r_y, float *r_u, float *r_v, int colorspace); +/** + * The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f + * + * Output YCC have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255. + */ void rgb_to_ycc(float r, float g, float b, float *r_y, float *r_cb, float *r_cr, int colorspace); void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v); void rgb_to_hsv_v(const float rgb[3], float r_hsv[3]); @@ -64,9 +81,19 @@ void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3]); void rgb_to_hsv_compat(float r, float g, float b, float *r_h, float *r_s, float *r_v); void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3]); unsigned int rgb_to_cpack(float r, float g, float b); +/** + * We define a 'cpack' here as a (3 byte color code) + * number that can be expressed like 0xFFAA66 or so. + * For that reason it is sensitive for endianness... with this function it works correctly. + * \see #imm_cpack + */ unsigned int hsv_to_cpack(float h, float s, float v); -/**************** Profile Transformations *****************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Profile Transformations + * \{ */ float srgb_to_linearrgb(float c); float linearrgb_to_srgb(float c); @@ -90,7 +117,11 @@ MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[ void BLI_init_srgb_conversion(void); -/**************** Alpha Transformations *****************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Alpha Transformations + * \{ */ MINLINE void premul_to_straight_v4_v4(float straight[4], const float premul[4]); MINLINE void premul_to_straight_v4(float color[4]); @@ -99,13 +130,34 @@ MINLINE void straight_to_premul_v4(float color[4]); MINLINE void straight_uchar_to_premul_float(float result[4], const unsigned char color[4]); MINLINE void premul_float_to_straight_uchar(unsigned char *result, const float color[4]); -/************************** Other *************************/ +/** \} */ +/* -------------------------------------------------------------------- */ +/** \name Other + * \{ */ + +/** + * If the requested RGB shade contains a negative weight for + * one of the primaries, it lies outside the color gamut + * accessible from the given triple of primaries. Desaturate + * it by adding white, equal quantities of R, G, and B, enough + * to make RGB all positive. The function returns 1 if the + * components were modified, zero otherwise. + */ int constrain_rgb(float *r, float *g, float *b); void minmax_rgb(short c[3]); +/** + * Clamp `hsv` to usable values. + */ void hsv_clamp_v(float hsv[3], float v_max); +/** + * Applies an HUE offset to a float RGB color. + */ void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset); +/** + * Applies an HUE offset to a byte RGB color. + */ void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset); void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3]); @@ -113,11 +165,28 @@ void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4]); void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3]); void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4]); +/** + * ITU-R BT.709 primaries + * https://en.wikipedia.org/wiki/Relative_luminance + * + * Real values are: + * `Y = 0.2126390059(R) + 0.7151686788(G) + 0.0721923154(B)` + * according to: "Derivation of Basic Television Color Equations", RP 177-1993 + * + * As this sums slightly above 1.0, the document recommends to use: + * `0.2126(R) + 0.7152(G) + 0.0722(B)`, as used here. + * + * The high precision values are used to calculate the rounded byte weights so they add up to 255: + * `54(R) + 182(G) + 19(B)` + */ MINLINE float rgb_to_grayscale(const float rgb[3]); MINLINE unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3]); MINLINE int compare_rgb_uchar(const unsigned char a[3], const unsigned char b[3], const int limit); +/** + * Return triangle noise in [-0.5..1.5] range. + */ MINLINE float dither_random_value(float s, float t); MINLINE void float_to_byte_dither_v3( unsigned char b[3], const float f[3], float dither, float s, float t); @@ -145,7 +214,11 @@ MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack); void blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max); void wavelength_to_xyz_table(float *r_table, int width); -/********* lift/gamma/gain / ASC-CDL conversion ***********/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name lift/gamma/gain / ASC-CDL conversion + * \{ */ void lift_gamma_gain_to_asc_cdl(const float *lift, const float *gamma, @@ -158,6 +231,8 @@ void lift_gamma_gain_to_asc_cdl(const float *lift, # include "intern/math_color_inline.c" #endif +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index be10b302144..539bb338032 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -37,16 +37,26 @@ extern "C" { #endif -/********************************** Polygons *********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Polygons + * \{ */ float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3]); float normal_quad_v3( float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3]); +/** + * Computes the normal of a planar polygon See Graphics Gems for computing newell normal. + */ float normal_poly_v3(float n[3], const float verts[][3], unsigned int nr); MINLINE float area_tri_v2(const float v1[2], const float v2[2], const float v3[2]); MINLINE float area_squared_tri_v2(const float v1[2], const float v2[2], const float v3[2]); MINLINE float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]); + +/* Triangles */ + float area_tri_v3(const float v1[3], const float v2[3], const float v3[3]); float area_squared_tri_v3(const float v1[3], const float v2[3], const float v3[3]); float area_tri_signed_v3(const float v1[3], @@ -68,38 +78,88 @@ float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float void cross_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3]); MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2]); void cross_poly_v3(float n[3], const float verts[][3], unsigned int nr); +/** + * Scalar cross product of a 2d polygon. + * + * - equivalent to `area * 2` + * - useful for checking polygon winding (a positive value is clockwise). + */ float cross_poly_v2(const float verts[][2], unsigned int nr); -/********************************* Planes **********************************/ +/** \} */ +/* -------------------------------------------------------------------- */ +/** \name Planes + * \{ */ + +/** + * Calculate a plane from a point and a direction, + * \note \a point_no isn't required to be normalized. + */ void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3]); +/** + * Get a point and a direction from a plane. + */ void plane_to_point_vector_v3(const float plane[4], float r_plane_co[3], float r_plane_no[3]); +/** + * Version of #plane_to_point_vector_v3 that gets a unit length vector. + */ void plane_to_point_vector_v3_normalized(const float plane[4], float r_plane_co[3], float r_plane_no[3]); MINLINE float plane_point_side_v3(const float plane[4], const float co[3]); -/********************************* Volume **********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Volume + * \{ */ +/** + * The volume from a tetrahedron, points can be in any order + */ float volume_tetrahedron_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); +/** + * The volume from a tetrahedron, normal pointing inside gives negative volume + */ float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); +/** + * The volume from a triangle that is made into a tetrahedron. + * This uses a simplified formula where the tip of the tetrahedron is in the world origin. + * Using this method, the total volume of a closed triangle mesh can be calculated. + * Note that you need to divide the result by 6 to get the actual volume. + */ float volume_tri_tetrahedron_signed_v3_6x(const float v1[3], const float v2[3], const float v3[3]); float volume_tri_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3]); +/** + * Check if the edge is convex or concave + * (depends on face winding) + * Copied from BM_edge_is_convex(). + */ bool is_edge_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); +/** + * Evaluate if entire quad is a proper convex quad + */ bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); bool is_poly_convex_v2(const float verts[][2], unsigned int nr); +/** + * Check if either of the diagonals along this quad create flipped triangles + * (normals pointing away from eachother). + * - (1 << 0): (v1-v3) is flipped. + * - (1 << 1): (v2-v4) is flipped. + */ int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); bool is_quad_flip_v3_first_third_fast(const float v1[3], const float v2[3], @@ -111,36 +171,88 @@ bool is_quad_flip_v3_first_third_fast_with_normal(const float v1[3], const float v4[3], const float normal[3]); -/********************************* Distance **********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Distance + * \{ */ +/** + * Distance p to line v1-v2 using Hesse formula (NO LINE PIECE!) + */ float dist_squared_to_line_v2(const float p[2], const float l1[2], const float l2[2]); float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]); +/** + * Distance p to line-piece v1-v2. + */ float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]); float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]); float dist_signed_squared_to_plane_v3(const float p[3], const float plane[4]); float dist_squared_to_plane_v3(const float p[3], const float plane[4]); +/** + * Return the signed distance from the point to the plane. + */ float dist_signed_to_plane_v3(const float p[3], const float plane[4]); float dist_to_plane_v3(const float p[3], const float plane[4]); -/* plane3 versions */ +/* Plane3 versions. */ + float dist_signed_squared_to_plane3_v3(const float p[3], const float plane[3]); float dist_squared_to_plane3_v3(const float p[3], const float plane[3]); float dist_signed_to_plane3_v3(const float p[3], const float plane[3]); float dist_to_plane3_v3(const float p[3], const float plane[3]); +/** + * Distance v1 to line-piece l1-l2 in 3D. + */ float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]); float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]); float dist_squared_to_line_v3(const float p[3], const float l1[3], const float l2[3]); float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3]); +/** + * Check if \a p is inside the 2x planes defined by `(v1, v2, v3)` + * where the 3x points define 2x planes. + * + * \param axis_ref: used when v1,v2,v3 form a line and to check if the corner is concave/convex. + * + * \note the distance from \a v1 & \a v3 to \a v2 doesn't matter + * (it just defines the planes). + * + * \return the lowest squared distance to either of the planes. + * where `(return < 0.0)` is outside. + * + * <pre> + * v1 + * + + * / + * x - out / x - inside + * / + * +----+ + * v2 v3 + * x - also outside + * </pre> + */ float dist_signed_squared_to_corner_v3v3v3(const float p[3], const float v1[3], const float v2[3], const float v3[3], const float axis_ref[3]); +/** + * Compute the squared distance of a point to a line (defined as ray). + * \param ray_origin: A point on the line. + * \param ray_direction: Normalized direction of the line. + * \param co: Point to which the distance is to be calculated. + */ float dist_squared_to_ray_v3_normalized(const float ray_origin[3], const float ray_direction[3], const float co[3]); +/** + * Find the closest point in a seg to a ray and return the distance squared. + * \param r_point: Is the point on segment closest to ray + * (or to ray_origin if the ray and the segment are parallel). + * \param r_depth: the distance of r_point projection on ray to the ray_origin. + */ float dist_squared_ray_to_seg_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], @@ -148,6 +260,9 @@ float dist_squared_ray_to_seg_v3(const float ray_origin[3], float r_point[3], float *r_depth); +/** + * Returns the coordinates of the nearest vertex and the farthest vertex from a plane (or normal). + */ void aabb_get_near_far_from_plane(const float plane_no[3], const float bbmin[3], const float bbmax[3], @@ -162,12 +277,17 @@ struct DistRayAABB_Precalc { void dist_squared_ray_to_aabb_v3_precalc(struct DistRayAABB_Precalc *neasrest_precalc, const float ray_origin[3], const float ray_direction[3]); +/** + * Returns the distance from a ray to a bound-box (projected on ray) + */ float dist_squared_ray_to_aabb_v3(const struct DistRayAABB_Precalc *data, const float bb_min[3], const float bb_max[3], float r_point[3], float *r_depth); -/* when there is no advantage to precalc. */ +/** + * Use when there is no advantage to pre-calculation. + */ float dist_squared_ray_to_aabb_v3_simple(const float ray_origin[3], const float ray_direction[3], const float bb_min[3], @@ -182,10 +302,17 @@ struct DistProjectedAABBPrecalc { float pmat[4][4]; float mval[2]; }; +/** + * \param projmat: Projection Matrix (usually perspective + * matrix multiplied by object matrix). + */ void dist_squared_to_projected_aabb_precalc(struct DistProjectedAABBPrecalc *precalc, const float projmat[4][4], const float winsize[2], const float mval[2]); +/** + * Returns the distance from a 2D coordinate to a bound-box (projected). + */ float dist_squared_to_projected_aabb(struct DistProjectedAABBPrecalc *data, const float bbmin[3], const float bbmax[3], @@ -205,21 +332,42 @@ double closest_to_line_v2_db(double r_close[2], const double p[2], const double l1[2], const double l2[2]); +/** + * Find closest point to p on line through (l1, l2) and return lambda, + * where (0 <= lambda <= 1) when cp is in the line segment (l1, l2). + */ float closest_to_line_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3]); +/** + * Point closest to v1 on line v2-v3 in 2D. + */ void closest_to_line_segment_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2]); +/** + * Point closest to v1 on line v2-v3 in 3D. + */ void closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3]); void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3]); +/** + * Find the closest point on a plane. + * + * \param r_close: Return coordinate + * \param plane: The plane to test against. + * \param pt: The point to find the nearest of + * + * \note non-unit-length planes are supported. + */ void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3]); void closest_to_plane3_normalized_v3(float r_close[3], const float plane[3], const float pt[3]); void closest_to_plane3_v3(float r_close[3], const float plane[3], const float pt[3]); -/* Set 'r' to the point in triangle (v1, v2, v3) closest to point 'p' */ +/** + * Set 'r' to the point in triangle (v1, v2, v3) closest to point 'p'. + */ void closest_on_tri_to_point_v3( float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3]); @@ -232,6 +380,13 @@ float ray_point_factor_v3(const float p[3], const float ray_origin[3], const float ray_direction[3]); +/** + * A simplified version of #closest_to_line_v3 + * we only need to return the `lambda` + * + * \param epsilon: avoid approaching divide-by-zero. + * Passing a zero will just check for nonzero division. + */ float line_point_factor_v3_ex(const float p[3], const float l1[3], const float l2[3], @@ -246,14 +401,25 @@ float line_point_factor_v2_ex(const float p[2], const float fallback); float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2]); +/** + * \note #isect_line_plane_v3() shares logic. + */ float line_plane_factor_v3(const float plane_co[3], const float plane_no[3], const float l1[3], const float l2[3]); +/** + * Ensure the distance between these points is no greater than 'dist'. + * If it is, scale them both into the center. + */ void limit_dist_v3(float v1[3], float v2[3], const float dist); -/******************************* Intersection ********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Intersection + * \{ */ /* TODO: int return value consistency. */ @@ -263,7 +429,13 @@ void limit_dist_v3(float v1[3], float v2[3], const float dist); #define ISECT_LINE_LINE_EXACT 1 #define ISECT_LINE_LINE_CROSS 2 +/** + * Intersect Line-Line, floats. + */ int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); +/** + * Returns a point on each segment that is closest to the other. + */ void isect_seg_seg_v3(const float a0[3], const float a1[3], const float b0[3], @@ -271,7 +443,21 @@ void isect_seg_seg_v3(const float a0[3], float r_a[3], float r_b[3]); +/* intersect Line-Line, shorts */ int isect_seg_seg_v2_int(const int v1[2], const int v2[2], const int v3[2], const int v4[2]); +/** + * Get intersection point of two 2D segments. + * + * \param endpoint_bias: Bias to use when testing for end-point overlap. + * A positive value considers intersections that extend past the endpoints, + * negative values contract the endpoints. + * Note the bias is applied to a 0-1 factor, not scaled to the length of segments. + * + * \returns intersection type: + * - -1: collinear. + * - 1: intersection. + * - 0: no intersection. + */ int isect_seg_seg_v2_point_ex(const float v0[2], const float v1[2], const float v2[2], @@ -284,12 +470,37 @@ bool isect_seg_seg_v2_simple(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); +/** + * If intersection == ISECT_LINE_LINE_CROSS or ISECT_LINE_LINE_NONE: + * <pre> + * pt = v1 + lambda * (v2 - v1) = v3 + mu * (v4 - v3) + * </pre> + * \returns intersection type: + * - ISECT_LINE_LINE_COLINEAR: collinear. + * - ISECT_LINE_LINE_EXACT: intersection at an endpoint of either. + * - ISECT_LINE_LINE_CROSS: interaction, not at an endpoint. + * - ISECT_LINE_LINE_NONE: no intersection. + * Also returns lambda and mu in r_lambda and r_mu. + */ int isect_seg_seg_v2_lambda_mu_db(const double v1[2], const double v2[2], const double v3[2], const double v4[2], double *r_lambda, double *r_mu); +/** + * \param l1, l2: Coordinates (point of line). + * \param sp, r: Coordinate and radius (sphere). + * \return r_p1, r_p2: Intersection coordinates. + * + * \note The order of assignment for intersection points (\a r_p1, \a r_p2) is predictable, + * based on the direction defined by `l2 - l1`, + * this direction compared with the normal of each point on the sphere: + * \a r_p1 always has a >= 0.0 dot product. + * \a r_p2 always has a <= 0.0 dot product. + * For example, when \a l1 is inside the sphere and \a l2 is outside, + * \a r_p1 will always be between \a l1 and \a l2. + */ int isect_line_sphere_v3(const float l1[3], const float l2[3], const float sp[3], @@ -303,8 +514,17 @@ int isect_line_sphere_v2(const float l1[2], float r_p1[2], float r_p2[2]); +/** + * Intersect Line-Line, floats - gives intersection point. + */ int isect_line_line_v2_point( const float v0[2], const float v1[2], const float v2[2], const float v3[2], float r_vi[2]); +/** + * \return The number of point of interests + * 0 - lines are collinear + * 1 - lines are coplanar, i1 is set to intersection + * 2 - i1 and i2 are the nearest points on line 1 (v1, v2) and line 2 (v3, v4) respectively + */ int isect_line_line_epsilon_v3(const float v1[3], const float v2[3], const float v3[3], @@ -318,12 +538,22 @@ int isect_line_line_v3(const float v1[3], const float v4[3], float r_i1[3], float r_i2[3]); +/** + * Intersection point strictly between the two lines + * \return false when no intersection is found. + */ bool isect_line_line_strict_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float vi[3], float *r_lambda); +/** + * Check if two rays are not parallel and returns a factor that indicates + * the distance from \a ray_origin_b to the closest point on ray-a to ray-b. + * + * \note Neither directions need to be normalized. + */ bool isect_ray_ray_epsilon_v3(const float ray_origin_a[3], const float ray_direction_a[3], const float ray_origin_b[3], @@ -338,30 +568,85 @@ bool isect_ray_ray_v3(const float ray_origin_a[3], float *r_lambda_a, float *r_lambda_b); +/** + * if clip is nonzero, will only return true if lambda is >= 0.0 + * (i.e. intersection point is along positive \a ray_direction) + * + * \note #line_plane_factor_v3() shares logic. + */ bool isect_ray_plane_v3(const float ray_origin[3], const float ray_direction[3], const float plane[4], float *r_lambda, const bool clip); +/** + * Check if a point is behind all planes. + */ bool isect_point_planes_v3(float (*planes)[4], int totplane, const float p[3]); +/** + * Check if a point is in front all planes. + * Same as isect_point_planes_v3 but with planes facing the opposite direction. + */ bool isect_point_planes_v3_negated(const float (*planes)[4], const int totplane, const float p[3]); +/** + * Intersect line/plane. + * + * \param r_isect_co: The intersection point. + * \param l1: The first point of the line. + * \param l2: The second point of the line. + * \param plane_co: A point on the plane to intersect with. + * \param plane_no: The direction of the plane (does not need to be normalized). + * + * \note #line_plane_factor_v3() shares logic. + */ bool isect_line_plane_v3(float r_isect_co[3], const float l1[3], const float l2[3], const float plane_co[3], const float plane_no[3]) ATTR_WARN_UNUSED_RESULT; +/** + * Intersect three planes, return the point where all 3 meet. + * See Graphics Gems 1 pg 305 + * + * \param plane_a, plane_b, plane_c: Planes. + * \param r_isect_co: The resulting intersection point. + */ bool isect_plane_plane_plane_v3(const float plane_a[4], const float plane_b[4], const float plane_c[4], float r_isect_co[3]) ATTR_WARN_UNUSED_RESULT; +/** + * Intersect two planes, return a point on the intersection and a vector + * that runs on the direction of the intersection. + * \note this is a slightly reduced version of #isect_plane_plane_plane_v3 + * + * \param plane_a, plane_b: Planes. + * \param r_isect_co: The resulting intersection point. + * \param r_isect_no: The resulting vector of the intersection. + * + * \note \a r_isect_no isn't unit length. + */ bool isect_plane_plane_v3(const float plane_a[4], const float plane_b[4], float r_isect_co[3], float r_isect_no[3]) ATTR_WARN_UNUSED_RESULT; +/** + * Intersect all planes, calling `callback_fn` for each point that intersects + * 3 of the planes that isn't outside any of the other planes. + * + * This can be thought of as calculating a convex-hull from an array of planes. + * + * \param eps_coplanar: Epsilon for testing if two planes are aligned (co-planar). + * \param eps_isect: Epsilon for testing of a point is behind any of the planes. + * + * \warning As complexity is a little under `O(N^3)`, this is only suitable for small arrays. + * + * \note This function could be optimized by some spatial structure. + */ bool isect_planes_v3_fn( const float planes[][4], const int planes_len, @@ -371,6 +656,11 @@ bool isect_planes_v3_fn( void *user_data); /* line/ray triangle */ + +/** + * Test if the line starting at p1 ending at p2 intersects the triangle v0..v2 + * return non zero if it does. + */ bool isect_line_segment_tri_v3(const float p1[3], const float p2[3], const float v0[3], @@ -378,6 +668,9 @@ bool isect_line_segment_tri_v3(const float p1[3], const float v2[3], float *r_lambda, float r_uv[2]); +/** + * Like #isect_line_segment_tri_v3, but allows epsilon tolerance around triangle. + */ bool isect_line_segment_tri_epsilon_v3(const float p1[3], const float p2[3], const float v0[3], @@ -394,6 +687,10 @@ bool isect_axial_line_segment_tri_v3(const int axis, const float v2[3], float *r_lambda); +/** + * Test if the ray starting at p1 going in d direction intersects the triangle v0..v2 + * return non zero if it does. + */ bool isect_ray_tri_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], @@ -417,6 +714,16 @@ bool isect_ray_tri_epsilon_v3(const float ray_origin[3], float *r_lambda, float r_uv[2], const float epsilon); +/** + * Intersect two triangles. + * + * \param r_i1, r_i2: Retrieve the overlapping edge between the 2 triangles. + * \param r_tri_a_edge_isect_count: Indicates how many edges in the first triangle are intersected. + * \return true when the triangles intersect. + * + * \note If it exists, \a r_i1 will be a point on the edge of the 1st triangle. + * \note intersections between coplanar triangles are currently undetected. + */ bool isect_tri_tri_v3_ex(const float tri_a[3][3], const float tri_b[3][3], float r_i1[3], @@ -438,7 +745,9 @@ bool isect_tri_tri_v2(const float p1[2], const float q2[2], const float r2[2]); -/* water-tight ray-cast (requires pre-calculation). */ +/** + * Water-tight ray-cast (requires pre-calculation). + */ struct IsectRayPrecalc { /* Maximal dimension `kz`, and orthogonal dimensions. */ int kx, ky, kz; @@ -456,7 +765,9 @@ bool isect_ray_tri_watertight_v3(const float ray_origin[3], const float v2[3], float *r_dist, float r_uv[2]); -/* slower version which calculates IsectRayPrecalc each time */ +/** + * Slower version which calculates #IsectRayPrecalc each time. + */ bool isect_ray_tri_watertight_v3_simple(const float ray_origin[3], const float ray_direction[3], const float v0[3], @@ -478,7 +789,8 @@ bool isect_ray_line_v3(const float ray_origin[3], const float v1[3], float *r_lambda); -/* point in polygon */ +/* Point in polygon. */ + bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr, @@ -488,27 +800,50 @@ bool isect_point_poly_v2_int(const int pt[2], const unsigned int nr, const bool use_holes); +/** + * Point in quad - only convex quads. + */ int isect_point_quad_v2( const float p[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2]); int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]); +/** + * Only single direction. + */ bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]); +/** + * \code{.unparsed} + * x1,y2 + * | \ + * | \ .(a,b) + * | \ + * x1,y1-- x2,y1 + * \endcode + */ int isect_point_tri_v2_int( const int x1, const int y1, const int x2, const int y2, const int a, const int b); bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]); +/** + * \param r_isect_co: The point \a p projected onto the triangle. + * \return True when \a p is inside the triangle. + * \note Its up to the caller to check the distance between \a p and \a r_vi + * against an error margin. + */ bool isect_point_tri_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3], float r_isect_co[3]); -/* axis-aligned bounding box */ +/** + * Axis-aligned bounding box. + */ bool isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], @@ -527,6 +862,13 @@ bool isect_ray_aabb_v3(const struct IsectRayAABB_Precalc *data, const float bb_min[3], const float bb_max[3], float *tmin); +/** + * Test a bounding box (AABB) for ray intersection. + * Assumes the ray is already local to the boundbox space. + * + * \note \a direction should be normalized + * if you intend to use the \a tmin or \a tmax distance results! + */ bool isect_ray_aabb_v3_simple(const float orig[3], const float dir[3], const float bb_min[3], @@ -539,6 +881,14 @@ bool isect_ray_aabb_v3_simple(const float orig[3], #define ISECT_AABB_PLANE_CROSS_ANY 1 #define ISECT_AABB_PLANE_IN_FRONT_ALL 2 +/** + * Checks status of an AABB in relation to a list of planes. + * + * \returns intersection type: + * - ISECT_AABB_PLANE_BEHIND_ONE (0): AABB is completely behind at least 1 plane; + * - ISECT_AABB_PLANE_CROSS_ANY (1): AABB intersects at least 1 plane; + * - ISECT_AABB_PLANE_IN_FRONT_ALL (2): AABB is completely in front of all planes; + */ int isect_aabb_planes_v3(const float (*planes)[4], const int totplane, const float bbmin[3], @@ -564,7 +914,12 @@ bool clip_segment_v3_plane_n(const float p1[3], bool point_in_slice_seg(float p[3], float l1[3], float l2[3]); -/****************************** Interpolation ********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Interpolation + * \{ */ + void interp_weights_tri_v3( float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3]); void interp_weights_quad_v3(float w[4], @@ -576,6 +931,7 @@ void interp_weights_quad_v3(float w[4], void interp_weights_poly_v3(float w[], float v[][3], const int n, const float co[3]); void interp_weights_poly_v2(float w[], float v[][2], const int n, const float co[2]); +/* (x1, v1)(t1=0)------(x2, v2)(t2=1), 0<t<1 --> (x, v)(t) */ void interp_cubic_v3(float x[3], float v[3], const float x1[3], @@ -584,8 +940,17 @@ void interp_cubic_v3(float x[3], const float v2[3], const float t); +/** + * Given an array with some invalid values this function interpolates valid values + * replacing the invalid ones. + */ int interp_sparse_array(float *array, const int list_size, const float skipval); +/** + * Given 2 triangles in 3D space, and a point in relation to the first triangle. + * calculate the location of a point in relation to the second triangle. + * Useful for finding relative positions with geometry. + */ void transform_point_by_tri_v3(float pt_tar[3], float const pt_src[3], const float tri_tar_p1[3], @@ -594,6 +959,10 @@ void transform_point_by_tri_v3(float pt_tar[3], const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3]); +/** + * Simply re-interpolates, + * assumes p_src is between \a l_src_p1-l_src_p2 + */ void transform_point_by_seg_v3(float p_dst[3], const float p_src[3], const float l_dst_p1[3], @@ -601,12 +970,32 @@ void transform_point_by_seg_v3(float p_dst[3], const float l_src_p1[3], const float l_src_p2[3]); +/** + * \note Using #cross_tri_v2 means locations outside the triangle are correctly weighted. + * + * \note This is *exactly* the same calculation as #resolve_tri_uv_v2, + * although it has double precision and is used for texture baking, so keep both. + */ void barycentric_weights_v2( const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); +/** + * A version of #barycentric_weights_v2 that doesn't allow negative weights. + * Useful when negative values cause problems and points are only + * ever slightly outside of the triangle. + */ void barycentric_weights_v2_clamped( const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); +/** + * still use 2D X,Y space but this works for verts transformed by a perspective matrix, + * using their 4th component as a weight + */ void barycentric_weights_v2_persp( const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3]); +/** + * same as #barycentric_weights_v2 but works with a quad, + * NOTE: untested for values outside the quad's bounds + * this is #interp_weights_poly_v2 expanded for quads only + */ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], @@ -614,20 +1003,47 @@ void barycentric_weights_v2_quad(const float v1[2], const float co[2], float w[4]); +/** + * \return false for degenerated triangles. + */ bool barycentric_coords_v2( const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); +/** + * \return + * - 0 if the point is outside of triangle. + * - 1 if the point is inside triangle. + * - 2 if it's on the edge. + */ int barycentric_inside_triangle_v2(const float w[3]); +/** + * Barycentric reverse + * + * Compute coordinates (u, v) for point \a st with respect to triangle (\a st0, \a st1, \a st2) + * + * \note same basic result as #barycentric_weights_v2, see its comment for details. + */ void resolve_tri_uv_v2( float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]); +/** + * Barycentric reverse 3d + * + * Compute coordinates (u, v) for point \a st with respect to triangle (\a st0, \a st1, \a st2) + */ void resolve_tri_uv_v3( float r_uv[2], const float st[3], const float st0[3], const float st1[3], const float st2[3]); +/** + * Bilinear reverse. + */ void resolve_quad_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]); +/** + * Bilinear reverse with derivatives. + */ void resolve_quad_uv_v2_deriv(float r_uv[2], float r_deriv[2][2], const float st[2], @@ -635,22 +1051,35 @@ void resolve_quad_uv_v2_deriv(float r_uv[2], const float st1[2], const float st2[2], const float st3[2]); +/** + * A version of resolve_quad_uv_v2 that only calculates the 'u'. + */ float resolve_quad_u_v2(const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]); -/* use to find the point of a UV on a face */ +/** + * Use to find the point of a UV on a face. + * Reverse of `resolve_*` functions. + */ void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3]); void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3]); -/***************************** View & Projection *****************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name View & Projection + * \{ */ void lookat_m4( float mat[4][4], float vx, float vy, float vz, float px, float py, float pz, float twist); void polarview_m4(float mat[4][4], float dist, float azimuth, float incidence, float twist); +/** + * Matches `glFrustum` result. + */ void perspective_m4(float mat[4][4], const float left, const float right, @@ -665,6 +1094,9 @@ void perspective_m4_fov(float mat[4][4], const float angle_down, const float nearClip, const float farClip); +/** + * Matches `glOrtho` result. + */ void orthographic_m4(float mat[4][4], const float left, const float right, @@ -672,8 +1104,18 @@ void orthographic_m4(float mat[4][4], const float top, const float nearClip, const float farClip); +/** + * Translate a matrix created by orthographic_m4 or perspective_m4 in XY coords + * (used to jitter the view). + */ void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x, const float y); +/** + * Frustum planes extraction from a projection matrix + * (homogeneous 4d vector representations of planes). + * + * plane parameters can be NULL if you do not need them. + */ void planes_from_projmat(const float mat[4][4], float left[4], float right[4], @@ -697,6 +1139,14 @@ void projmat_dimensions_db(const float winmat[4][4], double *r_near, double *r_far); +/** + * Creates a projection matrix for a small region of the viewport. + * + * \param projmat: Projection Matrix. + * \param win_size: Viewport Size. + * \param x_min, x_max, y_min, y_max: Coordinates of the subregion. + * \return r_projmat: Resulting Projection Matrix. + */ void projmat_from_subregion(const float projmat[4][4], const int win_size[2], const int x_min, @@ -708,7 +1158,11 @@ void projmat_from_subregion(const float projmat[4][4], int box_clip_bounds_m4(float boundbox[2][3], const float bounds[4], float winmat[4][4]); void box_minmax_bounds_m4(float min[3], float max[3], float boundbox[2][3], float mat[4][4]); -/********************************** Mapping **********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Mapping + * \{ */ void map_to_tube(float *r_u, float *r_v, const float x, const float y, const float z); void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z); @@ -718,7 +1172,11 @@ void map_to_plane_axis_angle_v2_v3v3fl(float r_co[2], const float axis[3], const float angle); -/********************************** Normals **********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Normals + * \{ */ void accumulate_vertex_normals_tri_v3(float n1[3], float n2[3], @@ -738,13 +1196,21 @@ void accumulate_vertex_normals_v3(float n1[3], const float co3[3], const float co4[3]); +/** + * Add weighted face normal component into normals of the face vertices. + * Caller must pass pre-allocated vdiffs of nverts length. + */ void accumulate_vertex_normals_poly_v3(float **vertnos, const float polyno[3], const float **vertcos, float vdiffs[][3], const int nverts); -/********************************* Tangents **********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Tangents + * \{ */ void tangent_from_uv_v3(const float uv1[2], const float uv2[2], @@ -755,8 +1221,31 @@ void tangent_from_uv_v3(const float uv1[2], const float n[3], float r_tang[3]); -/******************************** Vector Clouds ******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Vector Clouds + * \{ */ +/** + * Input: + * + * \param list_size: 4 lists as pointer to array[list_size] + * \param pos: current pos array of 'new' positions + * \param weight: current weight array of 'new'weights (may be NULL pointer if you have no weights) + * \param rpos: Reference rpos array of 'old' positions + * \param rweight: Reference rweight array of 'old'weights + * (may be NULL pointer if you have no weights). + * + * Output: + * + * \param lloc: Center of mass pos. + * \param rloc: Center of mass rpos. + * \param lrot: Rotation matrix. + * \param lscale: Scale matrix. + * + * pointers may be NULL if not needed + */ void vcloud_estimate_transform_v3(const int list_size, const float (*pos)[3], const float *weight, @@ -767,12 +1256,16 @@ void vcloud_estimate_transform_v3(const int list_size, float lrot[3][3], float lscale[3][3]); -/****************************** Spherical Harmonics *************************/ +/** \} */ -/* Uses 2nd order SH => 9 coefficients, stored in this order: - * 0 = (0, 0), - * 1 = (1, -1), 2 = (1, 0), 3 = (1, 1), - * 4 = (2, -2), 5 = (2, -1), 6 = (2, 0), 7 = (2, 1), 8 = (2, 2) */ +/* -------------------------------------------------------------------- */ +/** \name Spherical Harmonics + * + * Uses 2nd order SH => 9 coefficients, stored in this order: + * - 0 = `(0, 0)` + * - 1 = `(1, -1), 2 = (1, 0), 3 = (1, 1)` + * - 4 = `(2, -2), 5 = (2, -1), 6 = (2, 0), 7 = (2, 1), 8 = (2, 2)` + * \{ */ MINLINE void zero_sh(float r[9]); MINLINE void copy_sh_sh(float r[9], const float a[9]); @@ -785,7 +1278,11 @@ MINLINE float diffuse_shv3(const float r[9], const float v[3]); MINLINE void vec_fac_to_sh(float r[9], const float v[3], const float f); MINLINE void madd_sh_shfl(float r[9], const float sh[9], const float f); -/********************************* Form Factor *******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Form Factor + * \{ */ float form_factor_quad(const float p[3], const float n[3], @@ -805,37 +1302,117 @@ bool form_factor_visible_quad(const float p[3], float form_factor_hemi_poly( float p[3], float n[3], float v1[3], float v2[3], float v3[3], float v4[3]); +/** + * Same as axis_dominant_v3_to_m3, but flips the normal + */ void axis_dominant_v3_to_m3_negate(float r_mat[3][3], const float normal[3]); +/** + * \brief Normal to x,y matrix + * + * Creates a 3x3 matrix from a normal. + * This matrix can be applied to vectors so their 'z' axis runs along \a normal. + * In practice it means you can use x,y as 2d coords. \see + * + * \param r_mat: The matrix to return. + * \param normal: A unit length vector. + */ void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3]); +/** + * Get the 2 dominant axis values, 0==X, 1==Y, 2==Z. + */ MINLINE void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]); +/** + * Same as #axis_dominant_v3 but return the max value. + */ MINLINE float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3]) ATTR_WARN_UNUSED_RESULT; +/** + * Get the single dominant axis value, 0==X, 1==Y, 2==Z. + */ MINLINE int axis_dominant_v3_single(const float vec[3]); +/** + * The dominant axis of an orthogonal vector. + */ MINLINE int axis_dominant_v3_ortho_single(const float vec[3]); MINLINE int max_axis_v3(const float vec[3]); MINLINE int min_axis_v3(const float vec[3]); +/** + * Simple function to either: + * - Calculate how many triangles needed from the total number of polygons + loops. + * - Calculate the first triangle index from the polygon index & that polygons loop-start. + * + * \param poly_count: The number of polygons or polygon-index + * (3+ sided faces, 1-2 sided give incorrect results). + * \param corner_count: The number of corners (also called loop-index). + */ MINLINE int poly_to_tri_count(const int poly_count, const int corner_count); +/** + * Useful to calculate an even width shell, by taking the angle between 2 planes. + * The return value is a scale on the offset. + * no angle between planes is 1.0, as the angle between the 2 planes approaches 180d + * the distance gets very high, 180d would be inf, but this case isn't valid. + */ MINLINE float shell_angle_to_dist(const float angle); +/** + * Equivalent to `shell_angle_to_dist(angle_normalized_v3v3(a, b))`. + */ MINLINE float shell_v3v3_normalized_to_dist(const float a[3], const float b[3]); +/** + * Equivalent to `shell_angle_to_dist(angle_normalized_v2v2(a, b))`. + */ MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2]); +/** + * Equivalent to `shell_angle_to_dist(angle_normalized_v3v3(a, b) / 2)`. + */ MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[3]); +/** + * Equivalent to `shell_angle_to_dist(angle_normalized_v2v2(a, b) / 2)`. + */ MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[2]); -/********************************* Cubic (Bezier) *******************************/ +/** \} */ +/* -------------------------------------------------------------------- */ +/** \name Cubic (Bezier) + * \{ */ + +/** + * Return the value which the distance between points will need to be scaled by, + * to define a handle, given both points are on a perfect circle. + * + * Use when we want a bezier curve to match a circle as closely as possible. + * + * \note the return value will need to be divided by 0.75 for correct results. + */ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3]); -/********************************** Geodesics *********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Geodesics + * \{ */ +/** + * Utility for computing approximate geodesic distances on triangle meshes. + * + * Given triangle with vertex coordinates v0, v1, v2, and known geodesic distances + * dist1 and dist2 at v1 and v2, estimate a geodesic distance at vertex v0. + * + * From "Dart Throwing on Surfaces", EGSR 2009. Section 7, Geodesic Dart Throwing. + */ float geodesic_distance_propagate_across_triangle( const float v0[3], const float v1[3], const float v2[3], const float dist1, const float dist2); -/**************************** Inline Definitions ******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Inline Definitions + * \{ */ #if BLI_MATH_DO_INLINE # include "intern/math_geom_inline.c" @@ -845,6 +1422,8 @@ float geodesic_distance_propagate_across_triangle( # pragma GCC diagnostic pop #endif +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_math_interp.h b/source/blender/blenlib/BLI_math_interp.h index cc025b469e3..7179de12066 100644 --- a/source/blender/blenlib/BLI_math_interp.h +++ b/source/blender/blenlib/BLI_math_interp.h @@ -77,7 +77,8 @@ typedef void (*ewa_filter_read_pixel_cb)(void *userdata, int x, int y, float res void BLI_ewa_imp2radangle( float A, float B, float C, float F, float *a, float *b, float *th, float *ecc); -/* TODO(sergey): Consider making this function inlined, so the pixel read callback +/** + * TODO(sergey): Consider making this function inlined, so the pixel read callback * could also be inlined in order to avoid per-pixel function calls. */ void BLI_ewa_filter(const int width, diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 241acebffa3..4beb2508937 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -32,7 +32,11 @@ extern "C" { #endif -/********************************* Init **************************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Init + * \{ */ void zero_m2(float m[2][2]); void zero_m3(float m[3][3]); @@ -66,7 +70,11 @@ void swap_m4m4(float m1[4][4], float m2[4][4]); /* Build index shuffle matrix */ void shuffle_m4(float R[4][4], const int index[4]); -/******************************** Arithmetic *********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Arithmetic + * \{ */ void add_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]); void add_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]); @@ -81,14 +89,21 @@ void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]); void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4]); void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3]); void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]); +/** + * `R = A * B`, ignore the elements on the 4th row/column of A. + */ void mul_m3_m3m4(float R[3][3], const float A[3][3], const float B[4][4]); +/** + * `R = A * B`, ignore the elements on the 4th row/column of B. + */ void mul_m3_m4m3(float R[3][3], const float A[4][4], const float B[3][3]); void mul_m3_m4m4(float R[3][3], const float A[4][4], const float B[4][4]); -/* special matrix multiplies - * uniq: R <-- AB, R is neither A nor B - * pre: R <-- AR - * post: R <-- RB +/** + * Special matrix multiplies + * - uniq: `R <-- AB`, R is neither A nor B + * - pre: `R <-- AR` + * - post: `R <-- RB`. */ void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3]); void mul_m3_m3_pre(float R[3][3], const float A[3][3]); @@ -192,6 +207,7 @@ void mul_v4_m4v3_db(double r[4], const double mat[4][4], const double vec[3]); void mul_v2_m4v3(float r[2], const float M[4][4], const float v[3]); void mul_v2_m2v2(float r[2], const float M[2][2], const float v[2]); void mul_m2_v2(const float M[2][2], float v[2]); +/** Same as #mul_m4_v3() but doesn't apply translation component. */ void mul_mat3_m4_v3(const float M[4][4], float r[3]); void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3]); void mul_v3_mat3_m4v3_db(double r[3], const double M[4][4], const double v[3]); @@ -211,7 +227,18 @@ void mul_transposed_m3_v3(const float M[3][3], float r[3]); void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3]); void mul_m3_v3_double(const float M[3][3], double r[3]); +/** + * Combines transformations, handling scale separately in a manner equivalent + * to the Aligned Inherit Scale mode, in order to avoid creating shear. + * If A scale is uniform, the result is equivalent to ordinary multiplication. + * + * NOTE: this effectively takes output location from simple multiplication, + * and uses mul_m4_m4m4_split_channels for rotation and scale. + */ void mul_m4_m4m4_aligned_scale(float R[4][4], const float A[4][4], const float B[4][4]); +/** + * Separately combines location, rotation and scale of the input matrices. + */ void mul_m4_m4m4_split_channels(float R[4][4], const float A[4][4], const float B[4][4]); void mul_m3_fl(float R[3][3], float f); @@ -229,6 +256,16 @@ bool invert_m3(float R[3][3]); bool invert_m3_m3(float R[3][3], const float A[3][3]); bool invert_m4(float R[4][4]); bool invert_m4_m4(float R[4][4], const float A[4][4]); +/** + * Computes the inverse of mat and puts it in inverse. + * Uses Gaussian Elimination with partial (maximal column) pivoting. + * \return true on success (i.e. can always find a pivot) and false on failure. + * Mark Segal - 1992. + * + * \note this has worse performance than #EIG_invert_m4_m4 (Eigen), but e.g. + * for non-invertible scale matrices, finding a partial solution can + * be useful to have a valid local transform center, see T57767. + */ bool invert_m4_m4_fallback(float R[4][4], const float A[4][4]); /* double arithmetic (mixed float/double) */ @@ -239,10 +276,15 @@ void mul_v4d_m4v4d(double r[4], const float M[4][4], const double v[4]); void mul_v3_m3v3_db(double r[3], const double M[3][3], const double a[3]); void mul_m3_v3_db(const double M[3][3], double r[3]); -/****************************** Linear Algebra *******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Linear Algebra + * \{ */ void transpose_m3(float R[3][3]); void transpose_m3_m3(float R[3][3], const float M[3][3]); +/* seems obscure but in-fact a common operation */ void transpose_m3_m4(float R[3][3], const float M[4][4]); void transpose_m4(float R[4][4]); void transpose_m4_m4(float R[4][4], const float M[4][4]); @@ -262,10 +304,36 @@ void normalize_m4(float R[4][4]) ATTR_NONNULL(); void normalize_m4_m4_ex(float R[4][4], const float M[4][4], float r_scale[3]) ATTR_NONNULL(); void normalize_m4_m4(float R[4][4], const float M[4][4]) ATTR_NONNULL(); +/** + * Make an orthonormal matrix around the selected axis of the given matrix. + * + * \param axis: Axis to build the orthonormal basis around. + */ void orthogonalize_m3(float R[3][3], int axis); +/** + * Make an orthonormal matrix around the selected axis of the given matrix. + * + * \param axis: Axis to build the orthonormal basis around. + */ void orthogonalize_m4(float R[4][4], int axis); +/** + * Make an orthonormal matrix around the selected axis of the given matrix, + * in a way that is symmetric and stable to variations in the input, and + * preserving the value of the determinant, i.e. the overall volume change. + * + * \param axis: Axis to build the orthonormal basis around. + * \param normalize: Normalize the matrix instead of preserving volume. + */ void orthogonalize_m3_stable(float R[3][3], int axis, bool normalize); +/** + * Make an orthonormal matrix around the selected axis of the given matrix, + * in a way that is symmetric and stable to variations in the input, and + * preserving the value of the determinant, i.e. the overall volume change. + * + * \param axis: Axis to build the orthonormal basis around. + * \param normalize: Normalize the matrix instead of preserving volume. + */ void orthogonalize_m4_stable(float R[4][4], int axis, bool normalize); bool orthogonalize_m3_zero_axes(float R[3][3], const float unit_length); @@ -281,8 +349,8 @@ bool is_uniform_scaled_m4(const float m[4][4]); /* NOTE: 'adjoint' here means the adjugate (adjunct, "classical adjoint") matrix! * Nowadays 'adjoint' usually refers to the conjugate transpose, - * which for real-valued matrices is simply the transpose. - */ + * which for real-valued matrices is simply the transpose. */ + void adjoint_m2_m2(float R[2][2], const float M[2][2]); void adjoint_m3_m3(float R[3][3], const float M[3][3]); void adjoint_m4_m4(float R[4][4], const float M[4][4]); @@ -297,6 +365,13 @@ float determinant_m4(const float m[4][4]); #define PSEUDOINVERSE_EPSILON 1e-8f +/** + * Compute the Single Value Decomposition of an arbitrary matrix A + * That is compute the 3 matrices U,W,V with U column orthogonal (m,n) + * ,W a diagonal matrix and V an orthogonal square matrix `s.t.A = U.W.Vt`. + * From this decomposition it is trivial to compute the (pseudo-inverse) + * of `A` as `Ainv = V.Winv.transpose(U)`. + */ void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]); void pseudoinverse_m4_m4(float Ainv[4][4], const float A[4][4], float epsilon); void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon); @@ -306,18 +381,39 @@ bool has_zero_axis_m4(const float matrix[4][4]); void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4]); void invert_m3_m3_safe_ortho(float Ainv[3][3], const float A[3][3]); +/** + * A safe version of invert that uses valid axes, calculating the zero'd axis + * based on the non-zero ones. + * + * This works well for transformation matrices, when a single axis is zerod. + */ void invert_m4_m4_safe_ortho(float Ainv[4][4], const float A[4][4]); -/****************************** Transformations ******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Transformations + * \{ */ void scale_m3_fl(float R[3][3], float scale); void scale_m4_fl(float R[4][4], float scale); +/** + * This computes the overall volume scale factor of a transformation matrix. + * For an orthogonal matrix, it is the product of all three scale values. + * Returns a negative value if the transform is flipped by negative scale. + */ float mat3_to_volume_scale(const float M[3][3]); float mat4_to_volume_scale(const float M[4][4]); +/** + * This gets the average scale of a matrix, only use when your scaling + * data that has no idea of scale axis, examples are bone-envelope-radius + * and curve radius. + */ float mat3_to_scale(const float M[3][3]); float mat4_to_scale(const float M[4][4]); +/** Return 2D scale (in XY plane) of given mat4. */ float mat4_to_xy_scale(const float M[4][4]); void size_to_mat3(float R[3][3], const float size[3]); @@ -326,11 +422,31 @@ void size_to_mat4(float R[4][4], const float size[3]); void mat3_to_size(float size[3], const float M[3][3]); void mat4_to_size(float size[3], const float M[4][4]); +/** + * Extract scale factors from the matrix, with correction to ensure + * exact volume in case of a sheared matrix. + */ void mat4_to_size_fix_shear(float size[3], const float M[4][4]); void translate_m4(float mat[4][4], float tx, float ty, float tz); +/** + * Rotate a matrix in-place. + * + * \note To create a new rotation matrix see: + * #axis_angle_to_mat4_single, #axis_angle_to_mat3_single, #angle_to_mat2 + * (axis & angle args are compatible). + */ void rotate_m4(float mat[4][4], const char axis, const float angle); +/** Scale a matrix in-place. */ void rescale_m4(float mat[4][4], const float scale[3]); +/** + * Scale or rotate around a pivot point, + * a convenience function to avoid having to do inline. + * + * Since its common to make a scale/rotation matrix that pivots around an arbitrary point. + * + * Typical use case is to make 3x3 matrix, copy to 4x4, then pass to this function. + */ void transform_pivot_set_m4(float mat[4][4], const float pivot[3]); void mat4_to_rot(float rot[3][3], const float wmat[4][4]); @@ -341,16 +457,34 @@ void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3]); +/** + * Make a 4x4 matrix out of 3 transform components. + * Matrices are made in the order: `scale * rot * loc` + */ void loc_rot_size_to_mat4(float R[4][4], const float loc[3], const float rot[3][3], const float size[3]); +/** + * Make a 4x4 matrix out of 3 transform components. + * Matrices are made in the order: `scale * rot * loc` + * + * TODO: need to have a version that allows for rotation order. + */ void loc_eul_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], const float size[3]); +/** + * Make a 4x4 matrix out of 3 transform components. + * Matrices are made in the order: `scale * rot * loc` + */ void loc_eulO_size_to_mat4( float R[4][4], const float loc[3], const float eul[3], const float size[3], const short order); +/** + * Make a 4x4 matrix out of 3 transform components. + * Matrices are made in the order: `scale * rot * loc` + */ void loc_quat_size_to_mat4(float R[4][4], const float loc[3], const float quat[4], @@ -370,7 +504,32 @@ void blend_m4_m4m4(float out[4][4], const float src[4][4], const float srcweight); +/** + * A polar-decomposition-based interpolation between matrix A and matrix B. + * + * \note This code is about five times slower as the 'naive' interpolation done by #blend_m3_m3m3 + * (it typically remains below 2 usec on an average i74700, + * while #blend_m3_m3m3 remains below 0.4 usec). + * However, it gives expected results even with non-uniformly scaled matrices, + * see T46418 for an example. + * + * Based on "Matrix Animation and Polar Decomposition", by Ken Shoemake & Tom Duff + * + * \param R: Resulting interpolated matrix. + * \param A: Input matrix which is totally effective with `t = 0.0`. + * \param B: Input matrix which is totally effective with `t = 1.0`. + * \param t: Interpolation factor. + */ void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t); +/** + * Complete transform matrix interpolation, + * based on polar-decomposition-based interpolation from #interp_m3_m3m3. + * + * \param R: Resulting interpolated matrix. + * \param A: Input matrix which is totally effective with `t = 0.0`. + * \param B: Input matrix which is totally effective with `t = 1.0`. + * \param t: Interpolation factor. + */ void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t); bool is_negative_m3(const float mat[3][3]); @@ -382,16 +541,57 @@ bool is_zero_m4(const float mat[4][4]); bool equals_m3m3(const float mat1[3][3], const float mat2[3][3]); bool equals_m4m4(const float mat1[4][4], const float mat2[4][4]); -/* SpaceTransform helper */ +/** + * #SpaceTransform struct encapsulates all needed data to convert between two coordinate spaces + * (where conversion can be represented by a matrix multiplication). + * + * A #SpaceTransform is initialized using: + * - #BLI_SPACE_TRANSFORM_SETUP(&data, ob1, ob2) + * + * After that the following calls can be used: + * - Converts a coordinate in ob1 space to the corresponding ob2 space: + * #BLI_space_transform_apply(&data, co); + * - Converts a coordinate in ob2 space to the corresponding ob1 space: + * #BLI_space_transform_invert(&data, co); + * + * Same concept as #BLI_space_transform_apply and #BLI_space_transform_invert, + * but no is normalized after conversion (and not translated at all!): + * - #BLI_space_transform_apply_normal(&data, no); + * - #BLI_space_transform_invert_normal(&data, no); + */ typedef struct SpaceTransform { float local2target[4][4]; float target2local[4][4]; } SpaceTransform; +/** + * Global-invariant transform. + * + * This defines a matrix transforming a point in local space to a point in target space + * such that its global coordinates remain unchanged. + * + * In other words, if we have a global point P with local coordinates (x, y, z) + * and global coordinates (X, Y, Z), + * this defines a transform matrix TM such that (x', y', z') = TM * (x, y, z) + * where (x', y', z') are the coordinates of P' in target space + * such that it keeps (X, Y, Z) coordinates in global space. + */ void BLI_space_transform_from_matrices(struct SpaceTransform *data, const float local[4][4], const float target[4][4]); +/** + * Local-invariant transform. + * + * This defines a matrix transforming a point in global space + * such that its local coordinates (from local space to target space) remain unchanged. + * + * In other words, if we have a local point p with local coordinates (x, y, z) + * and global coordinates (X, Y, Z), + * this defines a transform matrix TM such that (X', Y', Z') = TM * (X, Y, Z) + * where (X', Y', Z') are the coordinates of p' in global space + * such that it keeps (x, y, z) coordinates in target space. + */ void BLI_space_transform_global_from_matrices(struct SpaceTransform *data, const float local[4][4], const float target[4][4]); @@ -403,7 +603,11 @@ void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float #define BLI_SPACE_TRANSFORM_SETUP(data, local, target) \ BLI_space_transform_from_matrices((data), (local)->obmat, (target)->obmat) -/*********************************** Other ***********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Other + * \{ */ void print_m3(const char *str, const float M[3][3]); void print_m4(const char *str, const float M[4][4]); @@ -411,6 +615,8 @@ void print_m4(const char *str, const float M[4][4]); #define print_m3_id(M) print_m3(STRINGIFY(M), M) #define print_m4_id(M) print_m4(STRINGIFY(M), M) +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h index 461b5a60c9d..bf447d954bc 100644 --- a/source/blender/blenlib/BLI_math_rotation.h +++ b/source/blender/blenlib/BLI_math_rotation.h @@ -38,25 +38,62 @@ extern "C" { #define RAD2DEGF(_rad) ((_rad) * (float)(180.0 / M_PI)) #define DEG2RADF(_deg) ((_deg) * (float)(M_PI / 180.0)) -/******************************** Quaternions ********************************/ -/* stored in (w, x, y, z) order */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Quaternions + * Stored in (w, x, y, z) order. + * \{ */ + +/* Initialize */ + +/* Convenience, avoids setting Y axis everywhere. */ -/* init */ void unit_axis_angle(float axis[3], float *angle); void unit_qt(float q[4]); void copy_qt_qt(float q[4], const float a[4]); /* arithmetic */ void mul_qt_qtqt(float q[4], const float a[4], const float b[4]); +/** + * \note + * Assumes a unit quaternion? + * + * in fact not, but you may want to use a unit quaternion read on... + * + * Shortcut for 'q v q*' when \a v is actually a quaternion. + * This removes the need for converting a vector to a quaternion, + * calculating q's conjugate and converting back to a vector. + * It also happens to be faster (17+,24* vs * 24+,32*). + * If \a q is not a unit quaternion, then \a v will be both rotated by + * the same amount as if q was a unit quaternion, and scaled by the square of + * the length of q. + * + * For people used to python mathutils, its like: + * def mul_qt_v3(q, v): (q * Quaternion((0.0, v[0], v[1], v[2])) * q.conjugated())[1:] + * + * \note Multiplying by 3x3 matrix is ~25% faster. + */ void mul_qt_v3(const float q[4], float r[3]); +/** + * Simple multiply. + */ void mul_qt_fl(float q[4], const float f); +/** + * Raise a unit quaternion to the specified power. + */ void pow_qt_fl_normalized(float q[4], const float f); void sub_qt_qtqt(float q[4], const float a[4], const float b[4]); void invert_qt(float q[4]); void invert_qt_qt(float q1[4], const float q2[4]); +/** + * This is just conjugate_qt for cases we know \a q is unit-length. + * we could use #conjugate_qt directly, but use this function to show intent, + * and assert if its ever becomes non-unit-length. + */ void invert_qt_normalized(float q[4]); void invert_qt_qt_normalized(float q1[4], const float q2[4]); void conjugate_qt(float q[4]); @@ -69,6 +106,14 @@ float normalize_qt_qt(float r[4], const float q[4]); bool is_zero_qt(const float q[4]); /* interpolation */ +/** + * Generic function for implementing slerp + * (quaternions and spherical vector coords). + * + * \param t: factor in [0..1] + * \param cosom: dot product from normalized vectors/quats. + * \param r_w: calculated weights. + */ void interp_dot_slerp(const float t, const float cosom, float w[2]); void interp_qt_qtqt(float q[4], const float a[4], const float b[4], const float t); void add_qt_qtqt(float q[4], const float a[4], const float b[4], const float t); @@ -77,24 +122,51 @@ void add_qt_qtqt(float q[4], const float a[4], const float b[4], const float t); void quat_to_mat3(float mat[3][3], const float q[4]); void quat_to_mat4(float mat[4][4], const float q[4]); +/** + * Apply the rotation of \a a to \a q keeping the values compatible with \a old. + * Avoid axis flipping for animated f-curves for eg. + */ void quat_to_compatible_quat(float q[4], const float a[4], const float old[4]); void mat3_normalized_to_quat(float q[4], const float mat[3][3]); void mat4_normalized_to_quat(float q[4], const float mat[4][4]); void mat3_to_quat(float q[4], const float mat[3][3]); void mat4_to_quat(float q[4], const float mat[4][4]); +/** + * Same as tri_to_quat() but takes pre-computed normal from the triangle + * used for ngons when we know their normal. + */ void tri_to_quat_ex(float quat[4], const float v1[3], const float v2[3], const float v3[3], const float no_orig[3]); +/** + * \return the length of the normal, use to test for degenerate triangles. + */ float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3]); void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag); -/* NOTE: v1 and v2 must be normalized. */ +/** + * Calculate a rotation matrix from 2 normalized vectors. + * \note `v1` and `v2` must be normalized. + */ void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3]); +/** + * \note Expects vectors to be normalized. + */ void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]); void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4]); +/** + * Decompose a quaternion into a swing rotation (quaternion with the selected + * axis component locked at zero), followed by a twist rotation around the axis. + * + * \param q: input quaternion. + * \param axis: twist axis in [0,1,2] + * \param r_swing: if not NULL, receives the swing quaternion. + * \param r_twist: if not NULL, receives the twist quaternion. + * \returns twist angle. + */ float quat_split_swing_and_twist(const float q[4], int axis, float r_swing[4], float r_twist[4]); float angle_normalized_qt(const float q[4]); @@ -107,7 +179,9 @@ float angle_signed_normalized_qtqt(const float q1[4], const float q2[4]); float angle_signed_qt(const float q[4]); float angle_signed_qtqt(const float q1[4], const float q2[4]); -/* TODO: don't what this is, but it's not the same as mat3_to_quat */ +/** + * TODO: don't what this is, but it's not the same as #mat3_to_quat. + */ void mat3_to_quat_is_ok(float q[4], const float mat[3][3]); /* other */ @@ -115,61 +189,120 @@ void print_qt(const char *str, const float q[4]); #define print_qt_id(q) print_qt(STRINGIFY(q), q) -/******************************** Axis Angle *********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Axis Angle + * \{ */ /* conversion */ void axis_angle_normalized_to_quat(float r[4], const float axis[3], const float angle); void axis_angle_to_quat(float r[4], const float axis[3], const float angle); +/** + * Axis angle to 3x3 matrix - safer version (normalization of axis performed). + */ void axis_angle_to_mat3(float R[3][3], const float axis[3], const float angle); +/** + * axis angle to 3x3 matrix + * + * This takes the angle with sin/cos applied so we can avoid calculating it in some cases. + * + * \param axis: rotation axis (must be normalized). + * \param angle_sin: sin(angle) + * \param angle_cos: cos(angle) + */ void axis_angle_normalized_to_mat3_ex(float mat[3][3], const float axis[3], const float angle_sin, const float angle_cos); void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], const float angle); +/** + * Axis angle to 4x4 matrix - safer version (normalization of axis performed). + */ void axis_angle_to_mat4(float R[4][4], const float axis[3], const float angle); +/** + * 3x3 matrix to axis angle. + */ void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float M[3][3]); +/** + * 4x4 matrix to axis angle. + */ void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float M[4][4]); void mat3_to_axis_angle(float axis[3], float *angle, const float M[3][3]); +/** + * 4x4 matrix to axis angle. + */ void mat4_to_axis_angle(float axis[3], float *angle, const float M[4][4]); +/** + * Quaternions to Axis Angle. + */ void quat_to_axis_angle(float axis[3], float *angle, const float q[4]); void angle_to_mat2(float R[2][2], const float angle); +/** + * Create a 3x3 rotation matrix from a single axis. + */ void axis_angle_to_mat3_single(float R[3][3], const char axis, const float angle); +/** + * Create a 4x4 rotation matrix from a single axis. + */ void axis_angle_to_mat4_single(float R[4][4], const char axis, const float angle); void axis_angle_to_quat_single(float q[4], const char axis, const float angle); -/****************************** Exponential Map ******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Exponential Map + * \{ */ + void quat_to_expmap(float expmap[3], const float q[4]); void quat_normalized_to_expmap(float expmap[3], const float q[4]); void expmap_to_quat(float r[4], const float expmap[3]); -/******************************** XYZ Eulers *********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name XYZ Eulers + * \{ */ +/* XYZ order. */ void eul_to_quat(float quat[4], const float eul[3]); +/* XYZ order */ void eul_to_mat3(float mat[3][3], const float eul[3]); +/* XYZ order */ void eul_to_mat4(float mat[4][4], const float eul[3]); +/* XYZ order */ void mat3_normalized_to_eul(float eul[3], const float mat[3][3]); +/* XYZ order */ void mat4_normalized_to_eul(float eul[3], const float mat[4][4]); void mat3_to_eul(float eul[3], const float mat[3][3]); void mat4_to_eul(float eul[3], const float mat[4][4]); +/* XYZ order */ void quat_to_eul(float eul[3], const float quat[4]); +/* XYZ order */ void mat3_normalized_to_compatible_eul(float eul[3], const float old[3], float mat[3][3]); void mat3_to_compatible_eul(float eul[3], const float old[3], float mat[3][3]); void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4]); +/* order independent! */ void compatible_eul(float eul[3], const float old[3]); +/* XYZ order */ void rotate_eul(float eul[3], const char axis, const float angle); void add_eul_euleul(float r_eul[3], float a[3], float b[3], const short order); void sub_eul_euleul(float r_eul[3], float a[3], float b[3], const short order); -/************************** Arbitrary Order Eulers ***************************/ +/** \} */ -/* warning: must match the eRotationModes in DNA_action_types.h +/* -------------------------------------------------------------------- */ +/** \name Arbitrary Order Eulers + * \{ */ + +/* WARNING: must match the #eRotationModes in `DNA_action_types.h` * order matters - types are saved to file. */ typedef enum eEulerRotationOrders { @@ -183,19 +316,48 @@ typedef enum eEulerRotationOrders { /* There are 6 more entries with duplicate entries included. */ } eEulerRotationOrders; +/** + * Construct quaternion from Euler angles (in radians). + */ void eulO_to_quat(float quat[4], const float eul[3], const short order); +/** + * Construct 3x3 matrix from Euler angles (in radians). + */ void eulO_to_mat3(float mat[3][3], const float eul[3], const short order); +/** + * Construct 4x4 matrix from Euler angles (in radians). + */ void eulO_to_mat4(float mat[4][4], const float eul[3], const short order); +/** + * Euler Rotation to Axis Angle. + */ void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], const short order); +/** + * The matrix is written to as 3 axis vectors. + */ void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order); +/** + * Convert 3x3 matrix to Euler angles (in radians). + */ void mat3_normalized_to_eulO(float eul[3], const short order, const float mat[3][3]); +/** + * Convert 4x4 matrix to Euler angles (in radians). + */ void mat4_normalized_to_eulO(float eul[3], const short order, const float mat[4][4]); void mat3_to_eulO(float eul[3], const short order, const float mat[3][3]); void mat4_to_eulO(float eul[3], const short order, const float mat[4][4]); +/** + * Convert quaternion to Euler angles (in radians). + */ void quat_to_eulO(float eul[3], const short order, const float quat[4]); +/** + * Axis Angle to Euler Rotation. + */ void axis_angle_to_eulO(float eul[3], const short order, const float axis[3], const float angle); +/* Uses 2 methods to retrieve eulers, and picks the closest. */ + void mat3_normalized_to_compatible_eulO(float eul[3], const float old[3], const short order, @@ -219,7 +381,11 @@ void quat_to_compatible_eulO(float eul[3], void rotate_eulO(float eul[3], const short order, char axis, float angle); -/******************************* Dual Quaternions ****************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Dual Quaternions + * \{ */ void copy_dq_dq(DualQuat *r, const DualQuat *dq); void normalize_dq(DualQuat *dq, float totw); @@ -229,21 +395,39 @@ void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq); void mat4_to_dquat(DualQuat *dq, const float basemat[4][4], const float mat[4][4]); void dquat_to_mat4(float R[4][4], const DualQuat *dq); +/** + * Axis matches #eTrackToAxis_Modes. + */ void quat_apply_track(float quat[4], short axis, short upflag); void vec_apply_track(float vec[3], short axis); +/** + * Lens/angle conversion (radians). + */ float focallength_to_fov(float focal_length, float sensor); float fov_to_focallength(float fov, float sensor); float angle_wrap_rad(float angle); float angle_wrap_deg(float angle); +/** + * Returns an angle compatible with angle_compat. + */ float angle_compat_rad(float angle, float angle_compat); +/** + * Each argument us an axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z'] + * where the first 2 are a source and the second 2 are the target. + */ bool mat3_from_axis_conversion( int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3]); +/** + * Use when the second axis can be guessed. + */ bool mat3_from_axis_conversion_single(int src_axis, int dst_axis, float r_mat[3][3]); +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_math_solvers.h b/source/blender/blenlib/BLI_math_solvers.h index 39a79efc7e2..32d4577899c 100644 --- a/source/blender/blenlib/BLI_math_solvers.h +++ b/source/blender/blenlib/BLI_math_solvers.h @@ -35,22 +35,61 @@ extern "C" { # pragma GCC diagnostic ignored "-Wredundant-decls" #endif -/********************************** Eigen Solvers *********************************/ +/* -------------------------------------------------------------------- */ +/** \name Eigen Solvers + * \{ */ +/** + * \brief Compute the eigen values and/or vectors of given 3D symmetric (aka adjoint) matrix. + * + * \param m3: the 3D symmetric matrix. + * \return r_eigen_values the computed eigen values (NULL if not needed). + * \return r_eigen_vectors the computed eigen vectors (NULL if not needed). + */ bool BLI_eigen_solve_selfadjoint_m3(const float m3[3][3], float r_eigen_values[3], float r_eigen_vectors[3][3]); +/** + * \brief Compute the SVD (Singular Values Decomposition) of given 3D matrix (m3 = USV*). + * + * \param m3: the matrix to decompose. + * \return r_U the computed left singular vector of \a m3 (NULL if not needed). + * \return r_S the computed singular values of \a m3 (NULL if not needed). + * \return r_V the computed right singular vector of \a m3 (NULL if not needed). + */ void BLI_svd_m3(const float m3[3][3], float r_U[3][3], float r_S[3], float r_V[3][3]); -/***************************** Simple Solvers ************************************/ +/** \} */ +/* -------------------------------------------------------------------- */ +/** \name Simple Solvers + * \{ */ + +/** + * \brief Solve a tridiagonal system of equations: + * + * a[i] * r_x[i-1] + b[i] * r_x[i] + c[i] * r_x[i+1] = d[i] + * + * Ignores a[0] and c[count-1]. Uses the Thomas algorithm, e.g. see wiki. + * + * \param r_x: output vector, may be shared with any of the input ones + * \return true if success + */ bool BLI_tridiagonal_solve( const float *a, const float *b, const float *c, const float *d, float *r_x, const int count); +/** + * \brief Solve a possibly cyclic tridiagonal system using the Sherman-Morrison formula. + * + * \param r_x: output vector, may be shared with any of the input ones + * \return true if success + */ bool BLI_tridiagonal_solve_cyclic( const float *a, const float *b, const float *c, const float *d, float *r_x, const int count); -/* Generic 3 variable Newton's method solver. */ +/** + * Generic 3 variable Newton's method solver. + */ typedef void (*Newton3D_DeltaFunc)(void *userdata, const float x[3], float r_delta[3]); typedef void (*Newton3D_JacobianFunc)(void *userdata, const float x[3], float r_jacobian[3][3]); typedef bool (*Newton3D_CorrectionFunc)(void *userdata, @@ -58,6 +97,21 @@ typedef bool (*Newton3D_CorrectionFunc)(void *userdata, float step[3], float x_next[3]); +/** + * \brief Solve a generic f(x) = 0 equation using Newton's method. + * + * \param func_delta: Callback computing the value of f(x). + * \param func_jacobian: Callback computing the Jacobian matrix of the function at x. + * \param func_correction: Callback for forcing the search into an arbitrary custom domain. + * May be NULL. + * \param userdata: Data for the callbacks. + * \param epsilon: Desired precision. + * \param max_iterations: Limit on the iterations. + * \param trace: Enables logging to console. + * \param x_init: Initial solution vector. + * \param result: Final result. + * \return true if success + */ bool BLI_newton3d_solve(Newton3D_DeltaFunc func_delta, Newton3D_JacobianFunc func_jacobian, Newton3D_CorrectionFunc func_correction, @@ -72,6 +126,8 @@ bool BLI_newton3d_solve(Newton3D_DeltaFunc func_delta, # pragma GCC diagnostic pop #endif +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_math_statistics.h b/source/blender/blenlib/BLI_math_statistics.h index 6e818f5c8df..e4524b49f3f 100644 --- a/source/blender/blenlib/BLI_math_statistics.h +++ b/source/blender/blenlib/BLI_math_statistics.h @@ -35,14 +35,36 @@ extern "C" { # pragma GCC diagnostic ignored "-Wredundant-decls" #endif -/********************************** Covariance Matrices *********************************/ +/* -------------------------------------------------------------------- */ +/** \name Covariance Matrices + * \{ */ +/** + * \brief Compute the covariance matrix of given set of nD coordinates. + * + * \param n: the dimension of the vectors (and hence, of the covariance matrix to compute). + * \param cos_vn: the nD points to compute covariance from. + * \param nbr_cos_vn: the number of nD coordinates in cos_vn. + * \param center: the center (or mean point) of cos_vn. If NULL, + * it is assumed cos_vn is already centered. + * \param use_sample_correction: whether to apply sample correction + * (i.e. get 'sample variance' instead of 'population variance'). + * \return r_covmat the computed covariance matrix. + */ void BLI_covariance_m_vn_ex(const int n, const float *cos_vn, const int nbr_cos_vn, const float *center, const bool use_sample_correction, float *r_covmat); +/** + * \brief Compute the covariance matrix of given set of 3D coordinates. + * + * \param cos_v3: the 3D points to compute covariance from. + * \param nbr_cos_v3: the number of 3D coordinates in cos_v3. + * \return r_covmat the computed covariance matrix. + * \return r_center the computed center (mean) of 3D points (may be NULL). + */ void BLI_covariance_m3_v3n(const float (*cos_v3)[3], const int nbr_cos_v3, const bool use_sample_correction, @@ -53,6 +75,8 @@ void BLI_covariance_m3_v3n(const float (*cos_v3)[3], # pragma GCC diagnostic pop #endif +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_math_time.h b/source/blender/blenlib/BLI_math_time.h index 671ec6f857f..643d1b51a08 100644 --- a/source/blender/blenlib/BLI_math_time.h +++ b/source/blender/blenlib/BLI_math_time.h @@ -27,7 +27,10 @@ extern "C" { #endif -/************************ Time constants definitions***************************/ +/* -------------------------------------------------------------------- */ +/** \name Time Constants Definitions + * \{ */ + #define SECONDS_IN_MILLISECONDS 0.001 #define SECONDS_IN_MINUTE 60.0 #define MINUTES_IN_HOUR 60.0 @@ -37,6 +40,15 @@ extern "C" { #define SECONDS_IN_DAY (MINUTES_IN_DAY * SECONDS_IN_MINUTE) #define SECONDS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE) +/** \} */ + +/** Explode given time value expressed in seconds, into a set of days, hours, minutes, seconds + * and/or milliseconds (depending on which return parameters are not NULL). + * + * \note The smallest given return parameter will get the potential fractional remaining time + * value. E.g. if you give `seconds=90.0` and do not pass `r_seconds` and `r_milliseconds`, + * `r_minutes` will be set to `1.5`. + */ void BLI_math_time_seconds_decompose(double seconds, double *r_days, double *r_hours, @@ -44,7 +56,15 @@ void BLI_math_time_seconds_decompose(double seconds, double *r_seconds, double *r_milliseconds); -/**************************** Inline Definitions ******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Inline Definitions + * \{ */ + +/* None. */ + +/** \} */ #ifdef __cplusplus } diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 62fd4a835ef..8f955076baf 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -33,7 +33,9 @@ extern "C" { #endif -/************************************* Init ***********************************/ +/* -------------------------------------------------------------------- */ +/** \name Init + * \{ */ #ifdef BLI_MATH_GCC_WARN_PRAGMA # pragma GCC diagnostic push @@ -57,6 +59,7 @@ MINLINE void swap_v3_v3(float a[3], float b[3]); MINLINE void swap_v4_v4(float a[4], float b[4]); /* unsigned char */ + MINLINE void copy_v2_v2_uchar(unsigned char r[2], const unsigned char a[2]); MINLINE void copy_v3_v3_uchar(unsigned char r[3], const unsigned char a[3]); MINLINE void copy_v4_v4_uchar(unsigned char r[4], const unsigned char a[4]); @@ -66,10 +69,13 @@ MINLINE void copy_v3_uchar(unsigned char r[3], const unsigned char a); MINLINE void copy_v4_uchar(unsigned char r[4], const unsigned char a); /* char */ + MINLINE void copy_v2_v2_char(char r[2], const char a[2]); MINLINE void copy_v3_v3_char(char r[3], const char a[3]); MINLINE void copy_v4_v4_char(char r[4], const char a[4]); + /* short */ + MINLINE void copy_v2_v2_short(short r[2], const short a[2]); MINLINE void copy_v3_v3_short(short r[3], const short a[3]); MINLINE void copy_v4_v4_short(short r[4], const short a[4]); @@ -78,30 +84,49 @@ MINLINE void zero_v3_int(int r[3]); MINLINE void copy_v2_v2_int(int r[2], const int a[2]); MINLINE void copy_v3_v3_int(int r[3], const int a[3]); MINLINE void copy_v4_v4_int(int r[4], const int a[4]); + /* double */ + MINLINE void zero_v3_db(double r[3]); MINLINE void copy_v2_v2_db(double r[2], const double a[2]); MINLINE void copy_v3_v3_db(double r[3], const double a[3]); MINLINE void copy_v4_v4_db(double r[4], const double a[4]); + /* short -> float */ + MINLINE void copy_v3fl_v3s(float r[3], const short a[3]); + /* int <-> float */ + MINLINE void copy_v2fl_v2i(float r[2], const int a[2]); + +/* int <-> float */ + MINLINE void round_v2i_v2fl(int r[2], const float a[2]); + /* double -> float */ + MINLINE void copy_v2fl_v2db(float r[2], const double a[2]); MINLINE void copy_v3fl_v3db(float r[3], const double a[3]); MINLINE void copy_v4fl_v4db(float r[4], const double a[4]); + /* float -> double */ + MINLINE void copy_v2db_v2fl(double r[2], const float a[2]); MINLINE void copy_v3db_v3fl(double r[3], const float a[3]); MINLINE void copy_v4db_v4fl(double r[4], const float a[4]); + /* float args -> vec */ + MINLINE void copy_v2_fl2(float v[2], float x, float y); MINLINE void copy_v3_fl3(float v[3], float x, float y, float z); MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w); -/********************************* Arithmetic ********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Arithmetic + * \{ */ MINLINE void add_v2_fl(float r[2], float f); MINLINE void add_v3_fl(float r[3], float f); @@ -149,11 +174,30 @@ MINLINE void mul_v4_v4(float r[4], const float a[4]); MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f); MINLINE void mul_v2_v2_cw(float r[2], const float mat[2], const float vec[2]); MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2]); +/** + * Convenience function to get the projected depth of a position. + * This avoids creating a temporary 4D vector and multiplying it - only for the 4th component. + * + * Matches logic for: + * + * \code{.c} + * float co_4d[4] = {co[0], co[1], co[2], 1.0}; + * mul_m4_v4(mat, co_4d); + * return co_4d[3]; + * \endcode + */ MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT; +/** + * Has the effect of #mul_m3_v3(), on a single axis. + */ MINLINE float dot_m3_v3_row_x(const float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT; MINLINE float dot_m3_v3_row_y(const float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT; MINLINE float dot_m3_v3_row_z(const float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT; +/** + * Has the effect of #mul_mat3_m4_v3(), on a single axis. + * (no adding translation) + */ MINLINE float dot_m4_v3_row_x(const float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT; MINLINE float dot_m4_v3_row_y(const float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT; MINLINE float dot_m4_v3_row_z(const float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT; @@ -180,12 +224,17 @@ MINLINE void negate_v3_v3(float r[3], const float a[3]); MINLINE void negate_v4(float r[4]); MINLINE void negate_v4_v4(float r[4], const float a[4]); +/* could add more... */ + MINLINE void negate_v3_short(short r[3]); MINLINE void negate_v3_db(double r[3]); MINLINE void invert_v2(float r[2]); MINLINE void invert_v3(float r[3]); -MINLINE void invert_v3_safe(float r[3]); /* Invert the vector, but leaves zero values as zero. */ +/** + * Invert the vector, but leaves zero values as zero. + */ +MINLINE void invert_v3_safe(float r[3]); MINLINE void abs_v2(float r[2]); MINLINE void abs_v2_v2(float r[2], const float a[2]); @@ -209,14 +258,26 @@ MINLINE double dot_v3v3_db(const double a[3], const double b[3]) ATTR_WARN_UNUSE MINLINE float cross_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT; MINLINE double cross_v2v2_db(const double a[2], const double b[2]) ATTR_WARN_UNUSED_RESULT; MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]); +/** + * Cross product suffers from severe precision loss when vectors are + * nearly parallel or opposite; doing the computation in double helps a lot. + */ MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3]); MINLINE void cross_v3_v3v3_db(double r[3], const double a[3], const double b[3]); +/** + * Excuse this fairly specific function, its used for polygon normals all over the place + * (could use a better name). + */ MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]); MINLINE void star_m3_v3(float rmat[3][3], const float a[3]); -/*********************************** Length **********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Length + * \{ */ MINLINE float len_squared_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT; MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT; @@ -241,8 +302,14 @@ MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESU MINLINE double len_v3_db(const double a[3]) ATTR_WARN_UNUSED_RESULT; MINLINE double len_squared_v3_db(const double v[3]) ATTR_WARN_UNUSED_RESULT; MINLINE float normalize_v2_length(float r[2], const float unit_scale); +/** + * \note any vectors containing `nan` will be zeroed out. + */ MINLINE float normalize_v2_v2_length(float r[2], const float a[2], const float unit_scale); MINLINE float normalize_v3_length(float r[3], const float unit_scale); +/** + * \note any vectors containing `nan` will be zeroed out. + */ MINLINE float normalize_v3_v3_length(float r[3], const float a[3], const float unit_scale); MINLINE double normalize_v3_length_db(double n[3], const double unit_scale); MINLINE double normalize_v3_v3_length_db(double r[3], const double a[3], const double unit_scale); @@ -254,16 +321,32 @@ MINLINE float normalize_v3_v3(float r[3], const float a[3]); MINLINE double normalize_v3_v3_db(double r[3], const double a[3]); MINLINE double normalize_v3_db(double n[3]); -/******************************* Interpolation *******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Interpolation + * \{ */ void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float t); void interp_v2_v2v2_db(double target[2], const double a[2], const double b[2], const double t); +/** + * Weight 3 2D vectors, + * 'w' must be unit length but is not a vector, just 3 weights. + */ void interp_v2_v2v2v2( float r[2], const float a[2], const float b[2], const float c[2], const float t[3]); void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t); void interp_v3_v3v3_db(double target[3], const double a[3], const double b[3], const double t); +/** + * Weight 3 vectors, + * 'w' must be unit length but is not a vector, just 3 weights. + */ void interp_v3_v3v3v3( float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]); +/** + * Weight 3 vectors, + * 'w' must be unit length but is not a vector, just 4 weights. + */ void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], @@ -282,11 +365,20 @@ void interp_v4_v4v4v4v4(float p[4], void interp_v3_v3v3v3_uv( float p[3], const float v1[3], const float v2[3], const float v3[3], const float uv[2]); +/** + * slerp, treat vectors as spherical coordinates + * \see #interp_qt_qtqt + * + * \return success + */ bool interp_v3_v3v3_slerp(float target[3], const float a[3], const float b[3], const float t) ATTR_WARN_UNUSED_RESULT; bool interp_v2_v2v2_slerp(float target[2], const float a[2], const float b[2], const float t) ATTR_WARN_UNUSED_RESULT; +/** + * Same as #interp_v3_v3v3_slerp but uses fallback values for opposite vectors. + */ void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], const float t); void interp_v2_v2v2_slerp_safe(float target[2], const float a[2], const float b[2], const float t); @@ -316,14 +408,34 @@ void mid_v3_v3v3v3v3( float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3]); void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const unsigned int nbr); +/** + * Specialized function for calculating normals. + * Fast-path for: + * + * \code{.c} + * add_v3_v3v3(r, a, b); + * normalize_v3(r) + * mul_v3_fl(r, angle_normalized_v3v3(a, b) / M_PI_2); + * \endcode + * + * We can use the length of (a + b) to calculate the angle. + */ void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3]); +/** + * Same as mid_v3_v3v3_angle_weighted + * but \a r is assumed to be accumulated normals, divided by their total. + */ void mid_v3_angle_weighted(float r[3]); void flip_v4_v4v4(float v[4], const float v1[4], const float v2[4]); void flip_v3_v3v3(float v[3], const float v1[3], const float v2[3]); void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2]); -/********************************* Comparison ********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Comparison + * \{ */ MINLINE bool is_zero_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT; MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT; @@ -378,24 +490,64 @@ MINLINE bool compare_size_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT; +/** + * <pre> + * + l1 + * | + * neg <- | -> pos + * | + * + l2 + * </pre> + * + * \return Positive value when 'pt' is left-of-line + * (looking from 'l1' -> 'l2'). + */ MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]) ATTR_WARN_UNUSED_RESULT; -/********************************** Angles ***********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Angles + * \{ */ /* - angle with 2 arguments is angle between vector. * - angle with 3 arguments is angle between 3 points at the middle point. * - angle_normalized_* is faster equivalent if vectors are normalized. */ + +/** + * Return the shortest angle in radians between the 2 vectors. + */ float angle_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT; float angle_signed_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT; float angle_v2v2v2(const float a[2], const float b[2], const float c[2]) ATTR_WARN_UNUSED_RESULT; float angle_normalized_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT; +/** + * Return the shortest angle in radians between the 2 vectors. + */ float angle_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT; +/** + * Return the angle in radians between vecs 1-2 and 2-3 in radians + * If v1 is a shoulder, v2 is the elbow and v3 is the hand, + * this would return the angle at the elbow. + * + * note that when v1/v2/v3 represent 3 points along a straight line + * that the angle returned will be pi (180deg), rather than 0.0. + */ float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT; +/** + * Quicker than full angle computation. + */ float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) ATTR_WARN_UNUSED_RESULT; +/** + * Quicker than full angle computation. + */ float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2]) ATTR_WARN_UNUSED_RESULT; +/** + * Angle between 2 vectors, about an axis (axis can be considered a plane). + */ float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT; @@ -403,6 +555,9 @@ float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT; float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT; +/** + * Angle between 2 vectors defined by 3 coords, about an axis (axis can be considered a plane). + */ float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], @@ -416,32 +571,107 @@ void angle_quad_v3( float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3]); void angle_poly_v3(float *angles, const float *verts[3], int len); -/********************************* Geometry **********************************/ +/** \} */ +/* -------------------------------------------------------------------- */ +/** \name Geometry + * \{ */ + +/** + * Project \a p onto \a v_proj + */ void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2]); +/** + * Project \a p onto \a v_proj + */ void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3]); void project_v3_v3v3_db(double out[3], const double p[3], const double v_proj[3]); +/** + * Project \a p onto a unit length \a v_proj + */ void project_v2_v2v2_normalized(float out[2], const float p[2], const float v_proj[2]); +/** + * Project \a p onto a unit length \a v_proj + */ void project_v3_v3v3_normalized(float out[3], const float p[3], const float v_proj[3]); +/** + * In this case plane is a 3D vector only (no 4th component). + * + * Projecting will make \a out a copy of \a p orthogonal to \a v_plane. + * + * \note If \a p is exactly perpendicular to \a v_plane, \a out will just be a copy of \a p. + * + * \note This function is a convenience to call: + * \code{.c} + * project_v3_v3v3(out, p, v_plane); + * sub_v3_v3v3(out, p, out); + * \endcode + */ void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3]); void project_plane_v2_v2v2(float out[2], const float p[2], const float v_plane[2]); void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3]); void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const float v_plane[2]); +/** + * Project a vector on a plane defined by normal and a plane point p. + */ void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3]); +/** + * Returns a reflection vector from a vector and a normal vector + * reflect = vec - ((2 * dot(vec, mirror)) * mirror). + * + * <pre> + * v + * + ^ + * \ | + * \| + * + normal: axis of reflection + * / + * / + * + + * out: result (negate for a 'bounce'). + * </pre> + */ void reflect_v3_v3v3(float out[3], const float vec[3], const float normal[3]); void reflect_v3_v3v3_db(double out[3], const double vec[3], const double normal[3]); +/** + * Takes a vector and computes 2 orthogonal directions. + * + * \note if \a n is n unit length, computed values will be too. + */ void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]); +/** + * Calculates \a p - a perpendicular vector to \a v + * + * \note return vector won't maintain same length. + */ void ortho_v3_v3(float out[3], const float v[3]); +/** + * no brainer compared to v3, just have for consistency. + */ void ortho_v2_v2(float out[2], const float v[2]); +/** + * Returns a vector bisecting the angle at b formed by a, b and c. + */ void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]); +/** + * Rotate a point \a p by \a angle around origin (0, 0) + */ void rotate_v2_v2fl(float r[2], const float p[2], const float angle); void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle); +/** + * Rotate a point \a p by \a angle around an arbitrary unit length \a axis. + * http://local.wasp.uwa.edu.au/~pbourke/geometry/ + */ void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axis[3], const float angle); -/*********************************** Other ***********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Other + * \{ */ void print_v2(const char *str, const float v[2]); void print_v3(const char *str, const float v[3]); @@ -464,6 +694,7 @@ void minmax_v2v2_v2(float min[2], float max[2], const float vec[2]); void minmax_v3v3_v3_array(float r_min[3], float r_max[3], const float (*vec_arr)[3], int nbr); +/** ensure \a v1 is \a dist from \a v2 */ void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist); void dist_ensure_v2_v2fl(float v1[2], const float v2[2], const float dist); @@ -476,8 +707,16 @@ MINLINE void clamp_v2_v2v2(float vec[2], const float min[2], const float max[2]) MINLINE void clamp_v3_v3v3(float vec[3], const float min[3], const float max[3]); MINLINE void clamp_v4_v4v4(float vec[4], const float min[4], const float max[4]); -/***************************** Array Functions *******************************/ -/* follow fixed length vector function conventions. */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Array Functions + * \{ */ + +/** + * Follow fixed length vector function conventions. + */ + double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size) ATTR_WARN_UNUSED_RESULT; @@ -532,7 +771,11 @@ void add_vn_vnvn_d(double *array_tar, const int size); void mul_vn_db(double *array_tar, const int size, const double f); -/**************************** Inline Definitions ******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Inline Definitions + * \{ */ #if BLI_MATH_DO_INLINE # include "intern/math_vector_inline.c" @@ -542,6 +785,8 @@ void mul_vn_db(double *array_tar, const int size, const double f); # pragma GCC diagnostic pop #endif +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h index b2e05b00735..4ac4712bc8c 100644 --- a/source/blender/blenlib/BLI_memarena.h +++ b/source/blender/blenlib/BLI_memarena.h @@ -29,8 +29,8 @@ extern "C" { #endif -/* A reasonable standard buffer size, big - * enough to not cause much internal fragmentation, +/** + * A reasonable standard buffer size, big enough to not cause much internal fragmentation, * small enough not to waste resources */ #define BLI_MEMARENA_STD_BUFSIZE MEM_SIZE_OPTIMAL(1 << 14) @@ -50,8 +50,22 @@ void *BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESU void *BLI_memarena_calloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2); +/** + * Transfer ownership of allocated blocks from `ma_src` into `ma_dst`, + * cleaning the contents of `ma_src`. + * + * \note Useful for multi-threaded tasks that need a thread-local #MemArena + * that is kept after the multi-threaded operation is completed. + * + * \note Avoid accumulating memory pools where possible + * as any unused memory in `ma_src` is wasted every merge. + */ void BLI_memarena_merge(MemArena *ma_dst, MemArena *ma_src) ATTR_NONNULL(1, 2); +/** + * Clear for reuse, avoids re-allocation when an arena may + * otherwise be free'd and recreated. + */ void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_memblock.h b/source/blender/blenlib/BLI_memblock.h index a9a3928394d..827ecc49739 100644 --- a/source/blender/blenlib/BLI_memblock.h +++ b/source/blender/blenlib/BLI_memblock.h @@ -38,6 +38,10 @@ typedef void (*MemblockValFreeFP)(void *val); BLI_memblock *BLI_memblock_create_ex(uint elem_size, uint chunk_size) ATTR_WARN_UNUSED_RESULT; void *BLI_memblock_alloc(BLI_memblock *mblk) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Reset elem count to 0 but keep as much memory allocated needed + * for at least the previous elem count. + */ void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1); void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1); @@ -56,6 +60,11 @@ typedef struct BLI_memblock_iter { void BLI_memblock_iternew(BLI_memblock *mblk, BLI_memblock_iter *iter) ATTR_NONNULL(); void *BLI_memblock_iterstep(BLI_memblock_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Direct access. elem is element index inside the chosen chunk. + * Double usage: You can set chunk to 0 and set the absolute elem index. + * The correct chunk will be retrieve. + */ void *BLI_memblock_elem_get(BLI_memblock *mblk, int chunk, int elem) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/blenlib/BLI_memiter.h b/source/blender/blenlib/BLI_memiter.h index abb1bec809d..6421a6eb6d6 100644 --- a/source/blender/blenlib/BLI_memiter.h +++ b/source/blender/blenlib/BLI_memiter.h @@ -35,10 +35,19 @@ struct BLI_memiter; typedef struct BLI_memiter BLI_memiter; -/* warning, ATTR_MALLOC flag on BLI_memiter_alloc causes crash, see: D2756 */ +/** + * \param chunk_size_min: Should be a power of two and + * significantly larger than the average element size used. + * + * While allocations of any size are supported, they won't be efficient + * (effectively becoming a single-linked list). + * + * Its intended that many elements can be stored per chunk. + */ BLI_memiter *BLI_memiter_create(unsigned int chunk_size) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL; void *BLI_memiter_alloc(BLI_memiter *mi, unsigned int size) + /* WARNING: `ATTR_MALLOC` attribute on #BLI_memiter_alloc causes crash, see: D2756. */ ATTR_RETURNS_NONNULL ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1); void BLI_memiter_alloc_from(BLI_memiter *mi, uint elem_size, const void *data_from) ATTR_NONNULL(1, 3); @@ -48,11 +57,15 @@ void BLI_memiter_destroy(BLI_memiter *mi) ATTR_NONNULL(1); void BLI_memiter_clear(BLI_memiter *mi) ATTR_NONNULL(1); unsigned int BLI_memiter_count(const BLI_memiter *mi) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); -/* utils */ +/* Utilities. */ + +/** + * Support direct lookup for the first item. + */ void *BLI_memiter_elem_first(BLI_memiter *mi); void *BLI_memiter_elem_first_size(BLI_memiter *mi, unsigned int *r_size); -/* private structure */ +/** Private structure. */ typedef struct BLI_memiter_handle { struct BLI_memiter_elem *elem; uint elem_left; diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h index 61b572a4943..d6abae36e00 100644 --- a/source/blender/blenlib/BLI_mempool.h +++ b/source/blender/blenlib/BLI_mempool.h @@ -44,19 +44,52 @@ void *BLI_mempool_alloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT A ATTR_NONNULL(1); void *BLI_mempool_calloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1); +/** + * Free an element from the mempool. + * + * \note doesn't protect against double frees, take care! + */ void BLI_mempool_free(BLI_mempool *pool, void *addr) ATTR_NONNULL(1, 2); +/** + * Empty the pool, as if it were just created. + * + * \param pool: The pool to clear. + * \param totelem_reserve: Optionally reserve how many items should be kept from clearing. + */ void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve) ATTR_NONNULL(1); +/** + * Wrap #BLI_mempool_clear_ex with no reserve set. + */ void BLI_mempool_clear(BLI_mempool *pool) ATTR_NONNULL(1); +/** + * Free the mempool its self (and all elements). + */ void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1); int BLI_mempool_len(const BLI_mempool *pool) ATTR_NONNULL(1); void *BLI_mempool_findelem(BLI_mempool *pool, unsigned int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Fill in \a data with pointers to each element of the mempool, + * to create lookup table. + * + * \param pool: Pool to create a table from. + * \param data: array of pointers at least the size of 'pool->totused' + */ void BLI_mempool_as_table(BLI_mempool *pool, void **data) ATTR_NONNULL(1, 2); +/** + * A version of #BLI_mempool_as_table that allocates and returns the data. + */ void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2); +/** + * Fill in \a data with the contents of the mempool. + */ void BLI_mempool_as_array(BLI_mempool *pool, void *data) ATTR_NONNULL(1, 2); +/** + * A version of #BLI_mempool_as_array that allocates and returns the data. + */ void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2); @@ -67,9 +100,10 @@ void BLI_mempool_set_memory_debug(void); /** * Iteration stuff. - * NOTE: this may easy to produce bugs with. + * \note this may easy to produce bugs with. */ -/* private structure */ + +/* Private structure. */ typedef struct BLI_mempool_iter { BLI_mempool *pool; struct BLI_mempool_chunk *curchunk; @@ -89,7 +123,13 @@ enum { BLI_MEMPOOL_ALLOW_ITER = (1 << 0), }; +/** + * Initialize a new mempool iterator, #BLI_MEMPOOL_ALLOW_ITER flag must be set. + */ void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter) ATTR_NONNULL(); +/** + * Step over the iterator, returning the mempool item or NULL. + */ void *BLI_mempool_iterstep(BLI_mempool_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_mesh_intersect.hh b/source/blender/blenlib/BLI_mesh_intersect.hh index f28be9bf59b..4aaed814bba 100644 --- a/source/blender/blenlib/BLI_mesh_intersect.hh +++ b/source/blender/blenlib/BLI_mesh_intersect.hh @@ -93,13 +93,16 @@ struct Plane { Plane(const mpq3 &norm_exact, const mpq_class &d_exact); Plane(const double3 &norm, const double d); - /* Test equality on the exact fields. */ + /** Test equality on the exact fields. */ bool operator==(const Plane &other) const; - /* Hash on the exact fields. */ + /** Hash on the exact fields. */ uint64_t hash() const; void make_canonical(); + /** + * This is wrong for degenerate planes, but we don't expect to call it on those. + */ bool exact_populated() const; void populate_exact(); }; @@ -395,10 +398,16 @@ struct BoundingBox { } }; -/** Assume bounding boxes have been expanded by a sufficient epsilon. */ +/** + * Assume bounding boxes have been expanded by a sufficient epsilon on all sides + * so that the comparisons against the bb bounds are sufficient to guarantee that + * if an overlap or even touching could happen, this will return true. + */ bool bbs_might_intersect(const BoundingBox &bb_a, const BoundingBox &bb_b); /** + * This is the main routine for calculating the self_intersection of a triangle mesh. + * * The output will have duplicate vertices merged and degenerate triangles ignored. * If the input has overlapping co-planar triangles, then there will be * as many duplicates as there are overlaps in each overlapping triangular region. @@ -406,7 +415,7 @@ bool bbs_might_intersect(const BoundingBox &bb_a, const BoundingBox &bb_b); * that the output triangle was a part of (input can have -1 for that field and then * the index in `tri[]` will be used as the original index). * The orig structure of the output #IMesh gives the originals for vertices and edges. - * NOTE: if the input tm_in has a non-empty orig structure, then it is ignored. + * \note if the input tm_in has a non-empty orig structure, then it is ignored. */ IMesh trimesh_self_intersect(const IMesh &tm_in, IMeshArena *arena); @@ -416,10 +425,17 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in, bool use_self, IMeshArena *arena); -/** Return an IMesh that is a triangulation of a mesh with general polygonal faces. */ +/** + * Return an #IMesh that is a triangulation of a mesh with general + * polygonal faces, #IMesh. + * Added diagonals will be distinguishable by having edge original + * indices of #NO_INDEX. + */ IMesh triangulate_polymesh(IMesh &imesh, IMeshArena *arena); -/** This has the side effect of populating verts in the #IMesh. */ +/** + * Writing the obj_mesh has the side effect of populating verts in the #IMesh. + */ void write_obj_mesh(IMesh &m, const std::string &objname); } /* namespace blender::meshintersect */ diff --git a/source/blender/blenlib/BLI_noise.h b/source/blender/blenlib/BLI_noise.h index 37afd8ee031..51aee9dc2ba 100644 --- a/source/blender/blenlib/BLI_noise.h +++ b/source/blender/blenlib/BLI_noise.h @@ -29,21 +29,65 @@ extern "C" { float BLI_noise_hnoise(float noisesize, float x, float y, float z); float BLI_noise_hnoisep(float noisesize, float x, float y, float z); +/** + * Original turbulence functions. + */ float BLI_noise_turbulence(float noisesize, float x, float y, float z, int nr); -/* newnoise: generic noise & turbulence functions +/** + * newnoise: generic noise & turbulence functions * to replace the above BLI_noise_hnoise/p & BLI_noise_turbulence/1. - * This is done so different noise basis functions can be used */ + * This is done so different noise basis functions can be used. + */ +/** + * newnoise: generic noise function for use with different `noisebasis`. + */ float BLI_noise_generic_noise( float noisesize, float x, float y, float z, bool hard, int noisebasis); +/** + * newnoise: generic turbulence function for use with different `noisebasis`. + */ float BLI_noise_generic_turbulence( float noisesize, float x, float y, float z, int oct, bool hard, int noisebasis); + /* newnoise: musgrave functions */ + +/** + * Procedural `fBm` evaluated at "point"; returns value stored in "value". + * + * \param H: is the fractal increment parameter. + * \param lacunarity: is the gap between successive frequencies. + * \param octaves: is the number of frequencies in the `fBm`. + */ float BLI_noise_mg_fbm( float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis); +/** + * Procedural multi-fractal evaluated at "point"; + * returns value stored in "value". + * + * \param H: determines the highest fractal dimension. + * \param lacunarity: is gap between successive frequencies. + * \param octaves: is the number of frequencies in the `fBm`. + * + * \note There used to be a parameter called `offset`, old docs read: + * is the zero offset, which determines multi-fractality. + */ float BLI_noise_mg_multi_fractal( float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis); +/** + * "Variable Lacunarity Noise" + * A distorted variety of Perlin noise. + */ float BLI_noise_mg_variable_lacunarity( float x, float y, float z, float distortion, int nbas1, int nbas2); +/** + * Heterogeneous procedural terrain function: stats by altitude method. + * Evaluated at "point"; returns value stored in "value". + * + * \param H: Determines the fractal dimension of the roughest areas. + * \param lacunarity: Is the gap between successive frequencies. + * \param octaves: Is the number of frequencies in the `fBm`. + * \param offset: Raises the terrain from `sea level`. + */ float BLI_noise_mg_hetero_terrain(float x, float y, float z, @@ -52,6 +96,14 @@ float BLI_noise_mg_hetero_terrain(float x, float octaves, float offset, int noisebasis); +/** + * Hybrid additive/multiplicative multi-fractal terrain model. + * + * Some good parameter values to start with: + * + * \param H: 0.25 + * \param offset: 0.7 + */ float BLI_noise_mg_hybrid_multi_fractal(float x, float y, float z, @@ -61,6 +113,15 @@ float BLI_noise_mg_hybrid_multi_fractal(float x, float offset, float gain, int noisebasis); +/** + * Ridged multi-fractal terrain model. + * + * Some good parameter values to start with: + * + * \param H: 1.0 + * \param offset: 1.0 + * \param gain: 2.0 + */ float BLI_noise_mg_ridged_multi_fractal(float x, float y, float z, @@ -71,9 +132,20 @@ float BLI_noise_mg_ridged_multi_fractal(float x, float gain, int noisebasis); /* newnoise: voronoi */ + +/** + * Not 'pure' Worley, but the results are virtually the same. + * Returns distances in da and point coords in `pa`. + */ void BLI_noise_voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype); -/* newnoise: BLI_noise_cell & BLI_noise_cell_v3 (for vector/point/color) */ +/** + * newnoise: BLI_noise_cell & BLI_noise_cell_v3 (for vector/point/color). + * idem, signed. + */ float BLI_noise_cell(float x, float y, float z); +/** + * Returns a vector/point/color in `r_ca`, using point hash-array directly. + */ void BLI_noise_cell_v3(float x, float y, float z, float r_ca[3]); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index e4774c58e84..9e2970f6013 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -29,27 +29,109 @@ extern "C" { #endif +/** + * Sets the specified environment variable to the specified value, + * and clears it if `val == NULL`. + */ void BLI_setenv(const char *env, const char *val) ATTR_NONNULL(1); +/** + * Only set an environment variable if already not there. + * Like Unix `setenv(env, val, 0);` + * + * (not used anywhere). + */ void BLI_setenv_if_new(const char *env, const char *val) ATTR_NONNULL(1); +/** + * Get an environment variable, result has to be used immediately. + * + * On windows #getenv gets its variables from a static copy of the environment variables taken at + * process start-up, causing it to not pick up on environment variables created during runtime. + * This function uses an alternative method to get environment variables that does pick up on + * runtime environment variables. The result will be UTF-8 encoded. + */ const char *BLI_getenv(const char *env) ATTR_NONNULL(1); +/** + * Returns in `string` the concatenation of `dir` and `file` (also with `relabase` on the + * front if specified and `dir` begins with "//"). Normalizes all occurrences of path + * separators, including ensuring there is exactly one between the copies of `dir` and `file`, + * and between the copies of `relabase` and `dir`. + * + * \param relabase: Optional prefix to substitute for "//" on front of `dir`. + * \param string: Area to return result. + */ void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file); +/** + * Ensures that the parent directory of `name` exists. + * + * \return true on success (i.e. given path now exists on file-system), false otherwise. + */ bool BLI_make_existing_file(const char *name); +/** + * Converts `/foo/bar.txt` to `/foo/` and `bar.txt` + * + * - Won't change \a string. + * - Won't create any directories. + * - Doesn't use CWD, or deal with relative paths. + * - Only fill's in \a dir and \a file when they are non NULL. + */ void BLI_split_dirfile( const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen); +/** + * Copies the parent directory part of string into `dir`, max length `dirlen`. + */ void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen); +/** + * Copies the leaf filename part of string into `file`, max length `filelen`. + */ void BLI_split_file_part(const char *string, char *file, const size_t filelen); +/** + * Returns a pointer to the last extension (e.g. the position of the last period). + * Returns NULL if there is no extension. + */ const char *BLI_path_extension(const char *filepath) ATTR_NONNULL(); +/** + * Append a filename to a dir, ensuring slash separates. + */ void BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__restrict file) ATTR_NONNULL(); +/** + * Simple appending of filename to dir, does not check for valid path! + * Puts result into `dst`, which may be same area as `dir`. + * + * \note Consider using #BLI_path_join for more general path joining + * that de-duplicates separators and can handle an arbitrary number of paths. + */ void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL(); +/** + * Join multiple strings into a path, ensuring only a single path separator between each, + * and trailing slash is kept. + * + * \note If you want a trailing slash, add `SEP_STR` as the last path argument, + * duplicate slashes will be cleaned up. + */ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *path_first, ...) ATTR_NONNULL(1, 3) ATTR_SENTINEL(0); +/** + * Like Python's `os.path.basename()` + * + * \return The pointer into \a path string immediately after last slash, + * or start of \a path if none found. + */ const char *BLI_path_basename(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; +/** + * Get an element of the path at an index, eg: + * "/some/path/file.txt" where an index of: + * - 0 or -3: "some" + * - 1 or -2: "path" + * - 2 or -1: "file.txt" + * + * Ignores multiple slashes at any point in the path (including start/end). + */ bool BLI_path_name_at_index(const char *__restrict path, const int index, int *__restrict r_offset, @@ -59,59 +141,217 @@ bool BLI_path_name_at_index(const char *__restrict path, bool BLI_path_contains(const char *container_path, const char *containee_path) ATTR_WARN_UNUSED_RESULT; +/** + * Returns pointer to the rightmost path separator in string. + */ const char *BLI_path_slash_rfind(const char *string) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; +/** + * Appends a slash to string if there isn't one there already. + * Returns the new length of the string. + */ int BLI_path_slash_ensure(char *string) ATTR_NONNULL(); +/** + * Removes the last slash and everything after it to the end of string, if there is one. + */ void BLI_path_slash_rstrip(char *string) ATTR_NONNULL(); +/** + * Returns pointer to the leftmost path separator in string. Not actually used anywhere. + */ const char *BLI_path_slash_find(const char *string) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; +/** + * Changes to the path separators to the native ones for this OS. + */ void BLI_path_slash_native(char *path) ATTR_NONNULL(); #ifdef _WIN32 bool BLI_path_program_extensions_add_win32(char *name, const size_t maxlen); #endif +/** + * Search for a binary (executable) + */ bool BLI_path_program_search(char *fullname, const size_t maxlen, const char *name); +/** + * \return true when `str` end with `ext` (case insensitive). + */ bool BLI_path_extension_check(const char *str, const char *ext) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; bool BLI_path_extension_check_n(const char *str, ...) ATTR_NONNULL(1) ATTR_SENTINEL(0); +/** + * \return true when `str` ends with any of the suffixes in `ext_array`. + */ bool BLI_path_extension_check_array(const char *str, const char **ext_array) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; +/** + * Semicolon separated wildcards, eg: `*.zip;*.py;*.exe` + * does `str` match any of the semicolon-separated glob patterns in #fnmatch. + */ bool BLI_path_extension_check_glob(const char *str, const char *ext_fnmatch) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; +/** + * Does basic validation of the given glob string, to prevent common issues from string + * truncation. + * + * For now, only forbids last group to be a wildcard-only one, if there are more than one group + * (i.e. things like `*.txt;*.cpp;*` are changed to `*.txt;*.cpp;`) + * + * \returns true if it had to modify given \a ext_fnmatch pattern. + */ bool BLI_path_extension_glob_validate(char *ext_fnmatch) ATTR_NONNULL(); +/** + * Removes any existing extension on the end of \a path and appends \a ext. + * \return false if there was no room. + */ bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) ATTR_NONNULL(); +/** + * Strip's trailing '.'s and adds the extension only when needed + */ bool BLI_path_extension_ensure(char *path, size_t maxlen, const char *ext) ATTR_NONNULL(); bool BLI_path_filename_ensure(char *filepath, size_t maxlen, const char *filename) ATTR_NONNULL(); +/** + * Looks for a sequence of decimal digits in string, preceding any filename extension, + * returning the integer value if found, or 0 if not. + * + * \param string: String to scan. + * \param head: Optional area to return copy of part of string prior to digits, + * or before dot if no digits. + * \param tail: Optional area to return copy of part of string following digits, + * or from dot if no digits. + * \param r_num_len: Optional to return number of digits found. + */ int BLI_path_sequence_decode(const char *string, char *head, char *tail, unsigned short *r_num_len); +/** + * Returns in area pointed to by string a string of the form `<head><pic><tail>`, + * where pic is formatted as `numlen` digits with leading zeroes. + */ void BLI_path_sequence_encode( char *string, const char *head, const char *tail, unsigned short numlen, int pic); +/** + * Remove redundant characters from \a path and optionally make absolute. + * + * \param relabase: The path this is relative to, or ignored when NULL. + * \param path: Can be any input, and this function converts it to a regular full path. + * Also removes garbage from directory paths, like `/../` or double slashes etc. + * + * \note \a path isn't protected for max string names. + */ void BLI_path_normalize(const char *relabase, char *path) ATTR_NONNULL(2); -/* Same as above but adds a trailing slash. */ +/** + * Cleanup file-path ensuring a trailing slash. + * + * \note Same as #BLI_path_normalize but adds a trailing slash. + */ void BLI_path_normalize_dir(const char *relabase, char *dir) ATTR_NONNULL(2); +/** + * Make given name safe to be used in paths. + * + * \return true if \a fname was changed, false otherwise. + * + * For now, simply replaces reserved chars (as listed in + * https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words ) + * by underscores ('_'). + * + * \note Space case ' ' is a bit of an edge case here - in theory it is allowed, + * but again can be an issue in some cases, so we simply replace it by an underscore too + * (good practice anyway). + * REMOVED based on popular demand (see T45900). + * Percent '%' char is a bit same case - not recommended to use it, + * but supported by all decent file-systems/operating-systems around. + * + * \note On Windows, it also ensures there is no '.' (dot char) at the end of the file, + * this can lead to issues. + * + * \note On Windows, it also checks for forbidden names + * (see https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx ). + */ bool BLI_filename_make_safe(char *fname) ATTR_NONNULL(1); +/** + * Make given path OS-safe. + * + * \return true if \a path was changed, false otherwise. + */ bool BLI_path_make_safe(char *path) ATTR_NONNULL(1); -/* Go back one directory. */ +/** + * Go back one directory. + * + * Replaces path with the path of its parent directory, returning true if + * it was able to find a parent directory within the path. + */ bool BLI_path_parent_dir(char *path) ATTR_NONNULL(); -/* Go back until the directory is found. */ +/** + * Go back until the directory is found. + * + * Strips off nonexistent (or non-accessible) sub-directories from the end of `dir`, + * leaving the path of the lowest-level directory that does exist and we can read. + */ bool BLI_path_parent_dir_until_exists(char *path) ATTR_NONNULL(); +/** + * If path begins with "//", strips that and replaces it with `basepath` directory. + * + * \note Also converts drive-letter prefix to something more sensible + * if this is a non-drive-letter-based system. + * + * \param path: The path to convert. + * \param basepath: The directory to base relative paths with. + * \return true if the path was relative (started with "//"). + */ bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL(); +/** + * Replaces "#" character sequence in last slash-separated component of `path` + * with frame as decimal integer, with leading zeroes as necessary, to make digits digits. + */ bool BLI_path_frame(char *path, int frame, int digits) ATTR_NONNULL(); +/** + * Replaces "#" character sequence in last slash-separated component of `path` + * with sta and end as decimal integers, with leading zeroes as necessary, to make digits + * digits each, with a hyphen in-between. + */ bool BLI_path_frame_range(char *path, int sta, int end, int digits) ATTR_NONNULL(); +/** + * Get the frame from a filename formatted by blender's frame scheme + */ bool BLI_path_frame_get(char *path, int *r_frame, int *numdigits) ATTR_NONNULL(); void BLI_path_frame_strip(char *path, char *ext) ATTR_NONNULL(); +/** + * Check if we have '#' chars, usable for #BLI_path_frame, #BLI_path_frame_range + */ bool BLI_path_frame_check_chars(const char *path) ATTR_NONNULL(); +/** + * Checks for relative path, expanding them relative to the current working directory. + * Returns true if the expansion was performed. + * + * \note Should only be called with command line paths. + * This is _not_ something Blender's internal paths support, instead they use the "//" prefix. + * In most cases #BLI_path_abs should be used instead. + */ bool BLI_path_abs_from_cwd(char *path, const size_t maxlen) ATTR_NONNULL(); +/** + * Replaces `file` with a relative version (prefixed by "//") such that #BLI_path_abs, given + * the same `relfile`, will convert it back to its original value. + */ void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL(); +/** + * Does path begin with the special "//" prefix that Blender uses to indicate + * a path relative to the .blend file. + */ bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT; +/** + * Return true if the path is a UNC share. + */ bool BLI_path_is_unc(const char *path); +/** + * Creates a display string from path to be used menus and the user interface. + * Like `bpy.path.display_name()`. + */ void BLI_path_to_display_name(char *display_name, int maxlen, const char *name) ATTR_NONNULL(); #if defined(WIN32) @@ -119,10 +359,22 @@ void BLI_path_normalize_unc_16(wchar_t *path_16); void BLI_path_normalize_unc(char *path_16, int maxlen); #endif +/** + * Appends a suffix to the string, fitting it before the extension + * + * string = Foo.png, suffix = 123, separator = _ + * Foo.png -> Foo_123.png + * + * \param string: original (and final) string + * \param maxlen: Maximum length of string + * \param suffix: String to append to the original string + * \param sep: Optional separator character + * \return true if succeeded + */ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char *sep) ATTR_NONNULL(); -/* path string comparisons: case-insensitive for Windows, case-sensitive otherwise */ +/* Path string comparisons: case-insensitive for Windows, case-sensitive otherwise. */ #if defined(WIN32) # define BLI_path_cmp BLI_strcasecmp # define BLI_path_ncmp BLI_strncasecmp @@ -131,8 +383,8 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char # define BLI_path_ncmp strncmp #endif -/* these values need to be hardcoded in structs, dna does not recognize defines */ -/* also defined in DNA_space_types.h */ +/* These values need to be hard-coded in structs, dna does not recognize defines */ +/* also defined in `DNA_space_types.h`. */ #ifndef FILE_MAXDIR # define FILE_MAXDIR 768 # define FILE_MAXFILE 256 @@ -155,7 +407,7 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char #define FILENAME_PARENT ".." #define FILENAME_CURRENT "." -/* Avoid calling strcmp on one or two chars! */ +/* Avoid calling `strcmp` on one or two chars! */ #define FILENAME_IS_PARENT(_n) (((_n)[0] == '.') && ((_n)[1] == '.') && ((_n)[2] == '\0')) #define FILENAME_IS_CURRENT(_n) (((_n)[0] == '.') && ((_n)[1] == '\0')) #define FILENAME_IS_CURRPAR(_n) \ diff --git a/source/blender/blenlib/BLI_polyfill_2d.h b/source/blender/blenlib/BLI_polyfill_2d.h index ca63ea5af87..d16c102ec86 100644 --- a/source/blender/blenlib/BLI_polyfill_2d.h +++ b/source/blender/blenlib/BLI_polyfill_2d.h @@ -26,6 +26,9 @@ extern "C" { struct MemArena; +/** + * A version of #BLI_polyfill_calc that uses a memory arena to avoid re-allocations. + */ void BLI_polyfill_calc_arena(const float (*coords)[2], const unsigned int coords_tot, const int coords_sign, @@ -33,6 +36,19 @@ void BLI_polyfill_calc_arena(const float (*coords)[2], struct MemArena *arena); +/** + * Triangulates the given (convex or concave) simple polygon to a list of triangle vertices. + * + * \param coords: 2D coordinates describing vertices of the polygon, + * in either clockwise or counterclockwise order. + * \param coords_tot: Total points in the array. + * \param coords_sign: Pass this when we know the sign in advance to avoid extra calculations. + * + * \param r_tris: This array is filled in with triangle indices in clockwise order. + * The length of the array must be `coords_tot - 2`. + * Indices are guaranteed to be assigned to unique triangles, with valid indices, + * even in the case of degenerate input (self intersecting polygons, zero area ears... etc). + */ void BLI_polyfill_calc(const float (*coords)[2], const unsigned int coords_tot, const int coords_sign, diff --git a/source/blender/blenlib/BLI_polyfill_2d_beautify.h b/source/blender/blenlib/BLI_polyfill_2d_beautify.h index 2c5296269ae..b0b97336a3b 100644 --- a/source/blender/blenlib/BLI_polyfill_2d_beautify.h +++ b/source/blender/blenlib/BLI_polyfill_2d_beautify.h @@ -27,6 +27,12 @@ extern "C" { struct Heap; struct MemArena; +/** + * The intention is that this calculates the output of #BLI_polyfill_calc + * \note assumes the \a coords form a boundary, + * so any edges running along contiguous (wrapped) indices, + * are ignored since the edges won't share 2 faces. + */ void BLI_polyfill_beautify(const float (*coords)[2], const unsigned int coords_tot, unsigned int (*tris)[3], @@ -35,6 +41,21 @@ void BLI_polyfill_beautify(const float (*coords)[2], struct MemArena *arena, struct Heap *eheap); +/** + * Assuming we have 2 triangles sharing an edge (2 - 4), + * check if the edge running from (1 - 3) gives better results. + * + * \param lock_degenerate: Use to avoid rotating out of a degenerate state: + * - When true, an existing zero area face on either side of the (2 - 4 + * split will return a positive value. + * - When false, the check must be non-biased towards either split direction. + * \param r_area: Return the area of the quad, + * This can be useful when comparing the return value with near zero epsilons. + * In this case the epsilon can be scaled by the area to avoid the return value + * of very large faces not having a reliable way to detect near-zero output. + * + * \return (negative number means the edge can be rotated, lager == better). + */ float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2], const float v2[2], const float v3[2], diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h index f8627952628..a1df6e1263e 100644 --- a/source/blender/blenlib/BLI_rand.h +++ b/source/blender/blenlib/BLI_rand.h @@ -31,7 +31,8 @@ extern "C" { #endif -/* RNG is an abstract random number generator type that avoids using globals. +/** + * RNG is an abstract random number generator type that avoids using globals. * Always use this instead of the global RNG unless you have a good reason, * the global RNG is not thread safe and will not give repeatable results. */ @@ -42,19 +43,34 @@ struct RNG_THREAD_ARRAY; typedef struct RNG_THREAD_ARRAY RNG_THREAD_ARRAY; struct RNG *BLI_rng_new(unsigned int seed); +/** + * A version of #BLI_rng_new that hashes the seed. + */ struct RNG *BLI_rng_new_srandom(unsigned int seed); struct RNG *BLI_rng_copy(struct RNG *rng) ATTR_NONNULL(1); void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1); void BLI_rng_seed(struct RNG *rng, unsigned int seed) ATTR_NONNULL(1); +/** + * Use a hash table to create better seed. + */ void BLI_rng_srandom(struct RNG *rng, unsigned int seed) ATTR_NONNULL(1); void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len) ATTR_NONNULL(1, 2); int BLI_rng_get_int(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); unsigned int BLI_rng_get_uint(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * \return Random value (0..1), but never 1.0. + */ double BLI_rng_get_double(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * \return Random value (0..1), but never 1.0. + */ float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); void BLI_rng_get_float_unit_v2(struct RNG *rng, float v[2]) ATTR_NONNULL(1, 2); void BLI_rng_get_float_unit_v3(struct RNG *rng, float v[3]) ATTR_NONNULL(1, 2); +/** + * Generate a random point inside given tri. + */ void BLI_rng_get_tri_sample_float_v2(struct RNG *rng, const float v1[2], const float v2[2], @@ -75,9 +91,16 @@ void BLI_rng_shuffle_bitmap(struct RNG *rng, unsigned int *bitmap, unsigned int ATTR_NONNULL(1, 2); /** Note that skipping is as slow as generating n numbers! */ +/** + * Simulate getting \a n random values. + * + * \note Useful when threaded code needs consistent values, independent of task division. + */ void BLI_rng_skip(struct RNG *rng, int n) ATTR_NONNULL(1); -/* fill an array with random numbers */ +/** + * Fill an array with random numbers. + */ void BLI_array_frand(float *ar, int count, unsigned int seed); /** Return a pseudo-random (hash) float from an integer value */ diff --git a/source/blender/blenlib/BLI_rand.hh b/source/blender/blenlib/BLI_rand.hh index 0c0dd464d4d..cc9e9b374d7 100644 --- a/source/blender/blenlib/BLI_rand.hh +++ b/source/blender/blenlib/BLI_rand.hh @@ -47,6 +47,9 @@ class RandomNumberGenerator { x_ = (static_cast<uint64_t>(seed) << 16) | lowseed; } + /** + * Set a randomized hash of the value as seed. + */ void seed_random(uint32_t seed); uint32_t get_uint32() @@ -117,6 +120,9 @@ class RandomNumberGenerator { float2 get_unit_float2(); float3 get_unit_float3(); + /** + * Generate a random point inside the given triangle. + */ float2 get_triangle_sample(float2 v1, float2 v2, float2 v3); float3 get_triangle_sample_3d(float3 v1, float3 v2, float3 v3); void get_bytes(MutableSpan<char> r_bytes); diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index 7950596933c..f4b1d051d16 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -34,12 +34,28 @@ struct rcti; extern "C" { #endif +/** + * Determine if a `rect` is empty. + * An empty `rect` is one with a zero (or negative) width or height. + * + * \return True if \a rect is empty. + */ bool BLI_rcti_is_empty(const struct rcti *rect); bool BLI_rctf_is_empty(const struct rctf *rect); void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax); void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax); +/** + * Check if X-min and Y-min are less than or equal to X-max and Y-max, respectively. + * If this returns false, #BLI_rctf_sanitize() can be called to address this. + * + * This is not a hard constraint or invariant for rectangles, in some cases it may be useful to + * have max < min. Usually this is what you'd want though. + */ bool BLI_rctf_is_valid(const struct rctf *rect); bool BLI_rcti_is_valid(const struct rcti *rect); +/** + * Ensure X-min and Y-min are less than or equal to X-max and Y-max, respectively. + */ void BLI_rctf_sanitize(struct rctf *rect); void BLI_rcti_sanitize(struct rcti *rect); void BLI_rctf_init_pt_radius(struct rctf *rect, const float xy[2], float size); @@ -50,10 +66,19 @@ void BLI_rcti_do_minmax_v(struct rcti *rect, const int xy[2]); void BLI_rctf_do_minmax_v(struct rctf *rect, const float xy[2]); void BLI_rcti_do_minmax_rcti(struct rcti *rect, const struct rcti *other); +/** + * Given 2 rectangles, transform a point from one to another. + */ void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2], const float xy_src[2]); +/** + * Calculate a 4x4 matrix representing the transformation between two rectangles. + * + * \note Multiplying a vector by this matrix does *not* + * give the same value as #BLI_rctf_transform_pt_v. + */ void BLI_rctf_transform_calc_m4_pivot_min_ex( const rctf *dst, const rctf *src, float matrix[4][4], uint x, uint y); void BLI_rctf_transform_calc_m4_pivot_min(const rctf *dst, const rctf *src, float matrix[4][4]); @@ -63,7 +88,13 @@ void BLI_rcti_translate(struct rcti *rect, int x, int y); void BLI_rcti_recenter(struct rcti *rect, int x, int y); void BLI_rctf_recenter(struct rctf *rect, float x, float y); void BLI_rcti_resize(struct rcti *rect, int x, int y); +/** + * Change width & height around the central X location. + */ void BLI_rcti_resize_x(struct rcti *rect, int x); +/** + * Change width & height around the central Y location. + */ void BLI_rcti_resize_y(struct rcti *rect, int y); void BLI_rcti_pad(struct rcti *rect, int pad_x, int pad_y); void BLI_rctf_pad(struct rctf *rect, float pad_x, float pad_y); @@ -83,6 +114,14 @@ void BLI_rctf_interp(struct rctf *rect, // void BLI_rcti_interp(struct rctf *rect, struct rctf *rect_a, struct rctf *rect_b, float fac); bool BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2]); bool BLI_rcti_clamp_pt_v(const struct rcti *rect, int xy[2]); +/** + * Clamp \a rect within \a rect_bounds, setting \a r_xy to the offset. + * + * Keeps the top left corner within the bounds, which for user interface + * elements is typically where the most important information is. + * + * \return true if a change is made. + */ bool BLI_rctf_clamp(struct rctf *rect, const struct rctf *rect_bounds, float r_xy[2]); bool BLI_rcti_clamp(struct rcti *rect, const struct rcti *rect_bounds, int r_xy[2]); bool BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, const float limit); @@ -101,7 +140,13 @@ bool BLI_rctf_isect_x(const rctf *rect, const float x); bool BLI_rctf_isect_y(const rctf *rect, const float y); bool BLI_rctf_isect_pt(const struct rctf *rect, const float x, const float y); bool BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2]); +/** + * \returns shortest distance from \a rect to x (0 if inside) + */ int BLI_rcti_length_x(const rcti *rect, const int x); +/** + * \returns shortest distance from \a rect to y (0 if inside) + */ int BLI_rcti_length_y(const rcti *rect, const int y); float BLI_rctf_length_x(const rctf *rect, const float x); float BLI_rctf_length_y(const rctf *rect, const float y); @@ -110,6 +155,9 @@ bool BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const fl bool BLI_rcti_isect_circle(const struct rcti *rect, const float xy[2], const float radius); bool BLI_rctf_isect_circle(const struct rctf *rect, const float xy[2], const float radius); bool BLI_rcti_inside_rcti(const rcti *rct_a, const rcti *rct_b); +/** + * is \a rct_b inside \a rct_a + */ bool BLI_rctf_inside_rctf(const rctf *rct_a, const rctf *rct_b); void BLI_rcti_union(struct rcti *rct_a, const struct rcti *rct_b); void BLI_rctf_union(struct rctf *rct_a, const struct rctf *rct_b); @@ -118,6 +166,9 @@ void BLI_rctf_rcti_copy(struct rctf *dst, const struct rcti *src); void BLI_rcti_rctf_copy_floor(struct rcti *dst, const struct rctf *src); void BLI_rcti_rctf_copy_round(struct rcti *dst, const struct rctf *src); +/** + * Expand the rectangle to fit a rotated \a src. + */ void BLI_rctf_rotate_expand(rctf *dst, const rctf *src, const float angle); void print_rctf(const char *str, const struct rctf *rect); diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h index 8f281023177..744d30397d4 100644 --- a/source/blender/blenlib/BLI_scanfill.h +++ b/source/blender/blenlib/BLI_scanfill.h @@ -123,6 +123,12 @@ void BLI_scanfill_begin_arena(ScanFillContext *sf_ctx, struct MemArena *arena); void BLI_scanfill_end_arena(ScanFillContext *sf_ctx, struct MemArena *arena); /* scanfill_utils.c */ + +/** + * Call before scan-fill to remove self intersections. + * + * \return false if no changes were made. + */ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx, ListBase *fillvertbase, ListBase *filledgebase); diff --git a/source/blender/blenlib/BLI_smallhash.h b/source/blender/blenlib/BLI_smallhash.h index f7aec716e9e..9492a252fed 100644 --- a/source/blender/blenlib/BLI_smallhash.h +++ b/source/blender/blenlib/BLI_smallhash.h @@ -34,8 +34,10 @@ typedef struct { void *val; } SmallHashEntry; -/* How much stack space to use before dynamically allocating memory. - * set to match one of the values in 'hashsizes' to avoid too many mallocs. */ +/** + * How much stack space to use before dynamically allocating memory. + * set to match one of the values in 'hashsizes' to avoid too many mallocs. + */ #define SMSTACKSIZE 131 typedef struct SmallHash { unsigned int nbuckets; @@ -53,8 +55,18 @@ typedef struct { void BLI_smallhash_init_ex(SmallHash *sh, const unsigned int nentries_reserve) ATTR_NONNULL(1); void BLI_smallhash_init(SmallHash *sh) ATTR_NONNULL(1); +/** + * \note does *not* free *sh itself! only the direct data! + */ void BLI_smallhash_release(SmallHash *sh) ATTR_NONNULL(1); void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *item) ATTR_NONNULL(1); +/** + * Inserts a new value to a key that may already be in ghash. + * + * Avoids #BLI_smallhash_remove, #BLI_smallhash_insert calls (double lookups) + * + * \returns true if a new key has been added. + */ bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item) ATTR_NONNULL(1); bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); void *BLI_smallhash_lookup(const SmallHash *sh, uintptr_t key) @@ -74,6 +86,12 @@ void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr /* void BLI_smallhash_print(SmallHash *sh); */ /* UNUSED */ #ifdef DEBUG +/** + * Measure how well the hash function performs + * (1.0 is perfect - no stepping needed). + * + * Smaller is better! + */ double BLI_smallhash_calc_quality(SmallHash *sh); #endif diff --git a/source/blender/blenlib/BLI_stack.h b/source/blender/blenlib/BLI_stack.h index b00bc0a2e57..653f5f61c9e 100644 --- a/source/blender/blenlib/BLI_stack.h +++ b/source/blender/blenlib/BLI_stack.h @@ -31,24 +31,73 @@ typedef struct BLI_Stack BLI_Stack; BLI_Stack *BLI_stack_new_ex(const size_t elem_size, const char *description, const size_t chunk_size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Create a new homogeneous stack with elements of 'elem_size' bytes. + */ BLI_Stack *BLI_stack_new(const size_t elem_size, const char *description) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Free the stack's data and the stack itself + */ void BLI_stack_free(BLI_Stack *stack) ATTR_NONNULL(); +/** + * Push a new item onto the stack. + * + * \return a pointer #BLI_Stack.elem_size + * bytes of uninitialized memory (caller must fill in). + */ void *BLI_stack_push_r(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Copies the source value onto the stack + * + * \note This copies #BLI_Stack.elem_size bytes from \a src, + * (the pointer itself is not stored). + * + * \param src: source data to be copied to the stack. + */ void BLI_stack_push(BLI_Stack *stack, const void *src) ATTR_NONNULL(); +/** + * A version of #BLI_stack_pop which fills in an array. + * + * \param dst: The destination array, + * must be at least (#BLI_Stack.elem_size * \a n) bytes long. + * \param n: The number of items to pop. + * + * \note The first item in the array will be last item added to the stack. + */ void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n) ATTR_NONNULL(); +/** + * A version of #BLI_stack_pop_n which fills in an array (in the reverse order). + * + * \note The first item in the array will be first item added to the stack. + */ void BLI_stack_pop_n_reverse(BLI_Stack *stack, void *dst, unsigned int n) ATTR_NONNULL(); +/** + * Retrieves and removes the top element from the stack. + * The value is copies to \a dst, which must be at least \a elem_size bytes. + * + * Does not reduce amount of allocated memory. + */ void BLI_stack_pop(BLI_Stack *stack, void *dst) ATTR_NONNULL(); void *BLI_stack_peek(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Removes the top element from the stack. + */ void BLI_stack_discard(BLI_Stack *stack) ATTR_NONNULL(); +/** + * Discards all elements without freeing. + */ void BLI_stack_clear(BLI_Stack *stack) ATTR_NONNULL(); size_t BLI_stack_count(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Returns true if the stack is empty, false otherwise + */ bool BLI_stack_is_empty(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index d3dc05edd9e..d949e0e7b69 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -33,23 +33,78 @@ extern "C" { #endif +/** + * Duplicates the first \a len bytes of cstring \a str + * into a newly mallocN'd string and returns it. \a str + * is assumed to be at least len bytes long. + * + * \param str: The string to be duplicated + * \param len: The number of bytes to duplicate + * \retval Returns the duplicated string + */ char *BLI_strdupn(const char *str, const size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Duplicates the cstring \a str into a newly mallocN'd + * string and returns it. + * + * \param str: The string to be duplicated + * \retval Returns the duplicated string + */ char *BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC; +/** + * Appends the two strings, and returns new mallocN'ed string + * \param str1: first string for copy + * \param str2: second string for append + * \retval Returns dst + */ char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC; +/** + * Like strncpy but ensures dst is always + * '\0' terminated. + * + * \param dst: Destination for copy + * \param src: Source string to copy + * \param maxncpy: Maximum number of characters to copy (generally + * the size of dst) + * \retval Returns dst + */ char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL(); +/** + * Like BLI_strncpy but ensures dst is always padded by given char, + * on both sides (unless src is empty). + * + * \param dst: Destination for copy + * \param src: Source string to copy + * \param pad: the char to use for padding + * \param maxncpy: Maximum number of characters to copy (generally the size of dst) + * \retval Returns dst + */ char *BLI_strncpy_ensure_pad(char *__restrict dst, const char *__restrict src, const char pad, size_t maxncpy) ATTR_NONNULL(); +/** + * Like strncpy but ensures dst is always + * '\0' terminated. + * + * \note This is a duplicate of #BLI_strncpy that returns bytes copied. + * And is a drop in replacement for 'snprintf(str, sizeof(str), "%s", arg);' + * + * \param dst: Destination for copy + * \param src: Source string to copy + * \param maxncpy: Maximum number of characters to copy (generally + * the size of dst) + * \retval The number of bytes copied (The only difference from BLI_strncpy). + */ size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); @@ -57,6 +112,18 @@ size_t BLI_strncpy_rlen(char *__restrict dst, size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Return the range of the quoted string (excluding quotes) `str` after `prefix`. + * + * A version of #BLI_str_quoted_substrN that calculates the range + * instead of un-escaping and allocating the result. + * + * \param str: String potentially including `prefix`. + * \param prefix: Quoted string prefix. + * \param r_start: The start of the quoted string (after the first quote). + * \param r_end: The end of the quoted string (before the last quote). + * \return True when a quoted string range could be found after `prefix`. + */ bool BLI_str_quoted_substr_range(const char *__restrict str, const char *__restrict prefix, int *__restrict r_start, @@ -67,91 +134,328 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC; #endif +/** + * Fills \a result with text within "" that appear after some the contents of \a prefix. + * i.e. for string `pose["apples"]` with prefix `pose[`, it will return `apples`. + * + * \param str: is the entire string to chop. + * \param prefix: is the part of the string to step over. + * \param result: The buffer to fill. + * \param result_maxlen: The maximum size of the buffer (including nil terminator). + * \return True if the prefix was found and the entire quoted string was copied into result. + * + * Assume that the strings returned must be freed afterwards, + * and that the inputs will contain data we want. + */ bool BLI_str_quoted_substr(const char *__restrict str, const char *__restrict prefix, char *result, size_t result_maxlen); +/** + * string with all instances of substr_old replaced with substr_new, + * Returns a copy of the c-string \a str into a newly #MEM_mallocN'd + * and returns it. + * + * \note A rather wasteful string-replacement utility, though this shall do for now. + * Feel free to replace this with an even safe + nicer alternative + * + * \param str: The string to replace occurrences of substr_old in + * \param substr_old: The text in the string to find and replace + * \param substr_new: The text in the string to find and replace + * \retval Returns the duplicated string + */ char *BLI_str_replaceN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC; +/** + * In-place replace every \a src to \a dst in \a str. + * + * \param str: The string to operate on. + * \param src: The character to replace. + * \param dst: The character to replace with. + */ void BLI_str_replace_char(char *string, char src, char dst) ATTR_NONNULL(); +/** + * Simple exact-match string replacement. + * + * \param replace_table: Array of source, destination pairs. + * + * \note Larger tables should use a hash table. + */ bool BLI_str_replace_table_exact(char *string, const size_t string_len, const char *replace_table[][2], int replace_table_len); +/** + * Portable replacement for #snprintf + */ size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...) ATTR_NONNULL(1, 3) ATTR_PRINTF_FORMAT(3, 4); +/** + * A version of #BLI_snprintf that returns `strlen(dst)` + */ size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...) ATTR_NONNULL(1, 3) ATTR_PRINTF_FORMAT(3, 4); +/** + * Portable replacement for `vsnprintf`. + */ size_t BLI_vsnprintf(char *__restrict buffer, size_t maxncpy, const char *__restrict format, va_list arg) ATTR_PRINTF_FORMAT(3, 0); +/** + * A version of #BLI_vsnprintf that returns `strlen(buffer)` + */ size_t BLI_vsnprintf_rlen(char *__restrict buffer, size_t maxncpy, const char *__restrict format, va_list arg) ATTR_PRINTF_FORMAT(3, 0); +/** + * Print formatted string into a newly #MEM_mallocN'd string + * and return it. + */ char *BLI_sprintfN(const char *__restrict format, ...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1, 2); +/** + * This roughly matches C and Python's string escaping with double quotes - `"`. + * + * Since every character may need escaping, + * it's common to create a buffer twice as large as the input. + * + * \param dst: The destination string, at least \a dst_maxncpy, typically `(strlen(src) * 2) + 1`. + * \param src: The un-escaped source string. + * \param dst_maxncpy: The maximum number of bytes allowable to copy. + * + * \note This is used for creating animation paths in blend files. + */ size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy) ATTR_NONNULL(); +/** + * This roughly matches C and Python's string escaping with double quotes - `"`. + * + * The destination will never be larger than the source, it will either be the same + * or up to half when all characters are escaped. + * + * \param dst: The destination string, at least the size of `strlen(src) + 1`. + * \param src: The escaped source string. + * \param src_maxncpy: The maximum number of bytes allowable to copy from `src`. + * \param dst_maxncpy: The maximum number of bytes allowable to copy into `dst`. + * \param r_is_complete: Set to true when + */ size_t BLI_str_unescape_ex(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy, /* Additional arguments. */ const size_t dst_maxncpy, bool *r_is_complete) ATTR_NONNULL(); +/** + * See #BLI_str_unescape_ex doc-string. + * + * This function makes the assumption that `dst` always has + * at least `src_maxncpy` bytes available. + * + * Use #BLI_str_unescape_ex if `dst` has a smaller fixed size. + * + * \note This is used for parsing animation paths in blend files (runs often). + */ size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy) ATTR_NONNULL(); +/** + * Find the first un-escaped quote in the string (to find the end of the string). + * + * \param str: Typically this is the first character in a quoted string. + * Where the character before `*str` would be `"`. + + * \return The pointer to the first un-escaped quote. + */ const char *BLI_str_escape_find_quote(const char *str) ATTR_NONNULL(); +/** + * Format ints with decimal grouping. + * 1000 -> 1,000 + * + * \param dst: The resulting string + * \param num: Number to format + * \return The length of \a dst + */ size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL(); +/** + * Format uint64_t with decimal grouping. + * 1000 -> 1,000 + * + * \param dst: The resulting string + * \param num: Number to format + * \return The length of \a dst + */ size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num) ATTR_NONNULL(); +/** + * Format a size in bytes using binary units. + * 1000 -> 1 KB + * Number of decimal places grows with the used unit (e.g. 1.5 MB, 1.55 GB, 1.545 TB). + * + * \param dst: The resulting string. + * Dimension of 14 to support largest possible value for \a bytes (#LLONG_MAX). + * \param bytes: Number to format. + * \param base_10: Calculate using base 10 (GB, MB, ...) or 2 (GiB, MiB, ...). + */ void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base_10) ATTR_NONNULL(); +/** + * Format a count to up to 6 places (plus '\0' terminator) string using long number + * names abbreviations. Used to produce a compact representation of large numbers. + * + * 1 -> 1 + * 15 -> 15 + * 155 -> 155 + * 1555 -> 1.6K + * 15555 -> 15.6K + * 155555 -> 156K + * 1555555 -> 1.6M + * 15555555 -> 15.6M + * 155555555 -> 156M + * 1000000000 -> 1B + * ... + * + * Length of 7 is the maximum of the resulting string, for example, `-15.5K\0`. + */ void BLI_str_format_attribute_domain_size(char dst[7], int number_to_format) ATTR_NONNULL(); +/** + * Compare two strings without regard to case. + * + * \retval True if the strings are equal, false otherwise. + */ int BLI_strcaseeq(const char *a, const char *b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Portable replacement for `strcasestr` (not available in MSVC) + */ char *BLI_strcasestr(const char *s, const char *find) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Variation of #BLI_strcasestr with string length limited to \a len + */ char *BLI_strncasestr(const char *s, const char *find, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BLI_strncasecmp(const char *s1, const char *s2, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Case insensitive, *natural* string comparison, + * keeping numbers in order. + */ int BLI_strcasecmp_natural(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Like strcmp, but will ignore any heading/trailing pad char for comparison. + * So e.g. if pad is '*', '*world' and 'world*' will compare equal. + */ int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * Determine the length of a fixed-size string. + */ size_t BLI_strnlen(const char *str, const size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void BLI_str_tolower_ascii(char *str, const size_t len) ATTR_NONNULL(); void BLI_str_toupper_ascii(char *str, const size_t len) ATTR_NONNULL(); +/** + * Strip white-space from end of the string. + */ void BLI_str_rstrip(char *str) ATTR_NONNULL(); +/** + * Strip trailing zeros from a float, eg: + * 0.0000 -> 0.0 + * 2.0010 -> 2.001 + * + * \param str: + * \param pad: + * \return The number of zeros stripped. + */ int BLI_str_rstrip_float_zero(char *str, const char pad) ATTR_NONNULL(); +/** + * Return index of a string in a string array. + * + * \param str: The string to find. + * \param str_array: Array of strings. + * \param str_array_len: The length of the array, or -1 for a NULL-terminated array. + * \return The index of str in str_array or -1. + */ int BLI_str_index_in_array_n(const char *__restrict str, const char **__restrict str_array, const int str_array_len) ATTR_NONNULL(); +/** + * Return index of a string in a string array. + * + * \param str: The string to find. + * \param str_array: Array of strings, (must be NULL-terminated). + * \return The index of str in str_array or -1. + */ int BLI_str_index_in_array(const char *__restrict str, const char **__restrict str_array) ATTR_NONNULL(); +/** + * Find if a string starts with another string. + * + * \param str: The string to search within. + * \param start: The string we look for at the start. + * \return If str starts with start. + */ bool BLI_str_startswith(const char *__restrict str, const char *__restrict start) ATTR_NONNULL(); +/** + * Find if a string ends with another string. + * + * \param str: The string to search within. + * \param end: The string we look for at the end. + * \return If str ends with end. + */ bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) ATTR_NONNULL(); bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, size_t length) ATTR_NONNULL(); +/** + * Find the first char matching one of the chars in \a delim, from left. + * + * \param str: The string to search within. + * \param delim: The set of delimiters to search for, as unicode values. + * \param sep: Return value, set to the first delimiter found (or NULL if none found). + * \param suf: Return value, set to next char after the first delimiter found + * (or NULL if none found). + * \return The length of the prefix (i.e. *sep - str). + */ size_t BLI_str_partition(const char *str, const char delim[], const char **sep, const char **suf) ATTR_NONNULL(); +/** + * Find the first char matching one of the chars in \a delim, from right. + * + * \param str: The string to search within. + * \param delim: The set of delimiters to search for, as unicode values. + * \param sep: Return value, set to the first delimiter found (or NULL if none found). + * \param suf: Return value, set to next char after the first delimiter found + * (or NULL if none found). + * \return The length of the prefix (i.e. *sep - str). + */ size_t BLI_str_rpartition(const char *str, const char delim[], const char **sep, const char **suf) ATTR_NONNULL(); +/** + * Find the first char matching one of the chars in \a delim, either from left or right. + * + * \param str: The string to search within. + * \param end: If non-NULL, the right delimiter of the string. + * \param delim: The set of delimiters to search for, as unicode values. + * \param sep: Return value, set to the first delimiter found (or NULL if none found). + * \param suf: Return value, set to next char after the first delimiter found + * (or NULL if none found). + * \param from_right: If %true, search from the right of \a str, else, search from its left. + * \return The length of the prefix (i.e. *sep - str). + */ size_t BLI_str_partition_ex(const char *str, const char *end, const char delim[], @@ -166,6 +470,16 @@ bool BLI_string_all_words_matched(const char *name, int (*words)[2], const int words_len); +/** + * Find the ranges needed to split \a str into its individual words. + * + * \param str: The string to search for words. + * \param len: Size of the string to search. + * \param delim: Character to use as a delimiter. + * \param r_words: Info about the words found. Set to [index, len] pairs. + * \param words_max: Max number of words to find + * \return The number of words found in \a str + */ int BLI_string_find_split_words(const char *str, const size_t len, const char delim, diff --git a/source/blender/blenlib/BLI_string_search.h b/source/blender/blenlib/BLI_string_search.h index 8057e5b75cb..b846a4d3c39 100644 --- a/source/blender/blenlib/BLI_string_search.h +++ b/source/blender/blenlib/BLI_string_search.h @@ -23,7 +23,16 @@ extern "C" { typedef struct StringSearch StringSearch; StringSearch *BLI_string_search_new(void); +/** + * Add a new possible result to the search. + * The caller keeps ownership of all parameters. + */ void BLI_string_search_add(StringSearch *search, const char *str, void *user_data); +/** + * Filter and sort all previously added search items. + * Returns an array containing the filtered user data. + * The caller has to free the returned array. + */ int BLI_string_search_query(StringSearch *search, const char *query, void ***r_data); void BLI_string_search_free(StringSearch *search); @@ -40,8 +49,24 @@ void BLI_string_search_free(StringSearch *search); namespace blender::string_search { +/** + * Computes the cost of transforming string a into b. The cost/distance is the minimal number of + * operations that need to be executed. Valid operations are deletion, insertion, substitution and + * transposition. + * + * This function is utf8 aware in the sense that it works at the level of individual code points + * (1-4 bytes long) instead of on individual bytes. + */ int damerau_levenshtein_distance(StringRef a, StringRef b); +/** + * Returns -1 when this is no reasonably good match. + * Otherwise returns the number of errors in the match. + */ int get_fuzzy_match_errors(StringRef query, StringRef full); +/** + * Splits a string into words and normalizes them (currently that just means converting to lower + * case). The returned strings are allocated in the given allocator. + */ void extract_normalized_words(StringRef str, LinearAllocator<> &allocator, Vector<StringRef, 64> &r_words); diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h index bf7547cc90b..1216af9216a 100644 --- a/source/blender/blenlib/BLI_string_utf8.h +++ b/source/blender/blenlib/BLI_string_utf8.h @@ -32,23 +32,84 @@ char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2); +/** + * Find first UTF-8 invalid byte in given \a str, of \a length bytes. + * + * \return the offset of the first invalid byte. + */ ptrdiff_t BLI_str_utf8_invalid_byte(const char *str, size_t length) ATTR_NONNULL(1); +/** + * Remove any invalid UTF-8 byte (taking into account multi-bytes sequence of course). + * + * \return number of stripped bytes. + */ int BLI_str_utf8_invalid_strip(char *str, size_t length) ATTR_NONNULL(1); -/* warning, can return -1 on bad chars */ +/** + * \return The size (in bytes) of a single UTF-8 char. + * \warning Can return -1 on bad chars. + */ int BLI_str_utf8_size(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * Use when we want to skip errors. + */ int BLI_str_utf8_size_safe(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); -/* copied from glib */ +/** + * \param p: a pointer to Unicode character encoded as UTF-8 + * + * Converts a sequence of bytes encoded as UTF-8 to a Unicode character. + * If \a p does not point to a valid UTF-8 encoded character, results are + * undefined. If you are not sure that the bytes are complete + * valid Unicode characters, you should use g_utf8_get_char_validated() + * instead. + * + * Return value: the resulting character + */ unsigned int BLI_str_utf8_as_unicode(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * UTF8 decoding that steps over the index (unless an error is encountered). + * + * \param p: The text to step over. + * \param p_len: The length of `p`. + * \param index: Index of `p` to step over. + * \return the code-point `(p + *index)` if there is a decoding error. + * + * \note Falls back to `LATIN1` for text drawing. + */ unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t p_len, size_t *__restrict index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 3); +/** + * UTF8 decoding that steps over the index (unless an error is encountered). + * + * \param p: The text to step over. + * \param p_len: The length of `p`. + * \param index: Index of `p` to step over. + * \return the code-point or #BLI_UTF8_ERR if there is a decoding error. + * + * \note The behavior for clipped text (where `p_len` limits decoding trailing bytes) + * must have the same behavior is encountering a nil byte, + * so functions that only use the first part of a string has matching behavior to functions + * that null terminate the text. + */ unsigned int BLI_str_utf8_as_unicode_step_or_error( const char *__restrict p, size_t p_len, size_t *__restrict index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 3); size_t BLI_str_utf8_from_unicode_len(unsigned int c) ATTR_WARN_UNUSED_RESULT; +/** + * BLI_str_utf8_from_unicode: + * + * \param c: a Unicode character code + * \param outbuf: output buffer, must have at least `outbuf_len` bytes of space. + * If the length required by `c` exceeds `outbuf_len`, + * the bytes available bytes will be zeroed and `outbuf_len` returned. + * + * Converts a single character to UTF-8. + * + * \return number of bytes written. + */ size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf, const size_t outbuf_len) ATTR_NONNULL(2); size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w, @@ -57,19 +118,57 @@ size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w, size_t BLI_str_utf32_as_utf8(char *__restrict dst, const char32_t *__restrict src, const size_t maxncpy) ATTR_NONNULL(1, 2); +/** + * \return The UTF-32 len in UTF-8. + */ size_t BLI_str_utf32_as_utf8_len(const char32_t *src) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +/** + * BLI_str_find_prev_char_utf8: + * \param str: pointer to the beginning of a UTF-8 encoded string + * \param p: pointer to some position within \a str + * + * Given a position \a p with a UTF-8 encoded string \a str, find the start + * of the previous UTF-8 character starting before. \a p Returns \a str_start if no + * UTF-8 characters are present in \a str_start before \a p. + * + * \a p does not have to be at the beginning of a UTF-8 character. No check + * is made to see if the character found is actually valid other than + * it starts with an appropriate byte. + * + * \return A pointer to the found character. + */ const char *BLI_str_find_prev_char_utf8(const char *p, const char *str_start) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1, 2); +/** + * \param p: a pointer to a position within a UTF-8 encoded string + * \param end: a pointer to the byte following the end of the string. + * + * Finds the start of the next UTF-8 character in the string after \a p + * + * \a p does not have to be at the beginning of a UTF-8 character. No check + * is made to see if the character found is actually valid other than + * it starts with an appropriate byte. + * + * \return a pointer to the found character or a pointer to the null terminating character '\0'. + */ const char *BLI_str_find_next_char_utf8(const char *p, const char *str_end) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1, 2); +/** + * \return the `wchar_t` length in UTF-8. + */ size_t BLI_wstrlen_utf8(const wchar_t *src) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes) ATTR_NONNULL(1, 2) ATTR_WARN_UNUSED_RESULT; size_t BLI_strlen_utf8(const char *strc) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_bytes) ATTR_NONNULL(1, 3); +/** + * \param strc: the string to measure the length. + * \param maxlen: the string length (in bytes) + * \return the unicode length (not in bytes!) + */ size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, @@ -79,10 +178,14 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL(1, 2); -/* count columns that character/string occupies, based on wcwidth.c */ +/** + * Count columns that character/string occupies (based on `wcwidth.co`). + */ int BLI_wcwidth(char32_t ucs) ATTR_WARN_UNUSED_RESULT; int BLI_wcswidth(const char32_t *pwcs, size_t n) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); -/* warning, can return -1 on bad chars */ +/** + * \warning can return -1 on bad chars. + */ int BLI_str_utf8_char_width(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); int BLI_str_utf8_char_width_safe(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); @@ -111,7 +214,8 @@ int BLI_str_utf8_offset_to_column(const char *str, int offset) ATTR_WARN_UNUSED_ int BLI_str_utf8_offset_from_column(const char *str, int column) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); -#define BLI_UTF8_MAX 6 /* mem */ +/** Size in bytes. */ +#define BLI_UTF8_MAX 6 #define BLI_UTF8_WIDTH_MAX 2 /* columns */ #define BLI_UTF8_ERR ((unsigned int)-1) diff --git a/source/blender/blenlib/BLI_string_utils.h b/source/blender/blenlib/BLI_string_utils.h index 277bb6fac05..07fd4882513 100644 --- a/source/blender/blenlib/BLI_string_utils.h +++ b/source/blender/blenlib/BLI_string_utils.h @@ -36,33 +36,71 @@ struct ListBase; typedef bool (*UniquenameCheckCallback)(void *arg, const char *name); +/** + * Looks for a numeric suffix preceded by `delim` character on the end of + * name, puts preceding part into *left and value of suffix into *nr. + * Returns the length of *left. + * + * Foo.001 -> "Foo", 1 + * Returning the length of "Foo" + * + * \param left: Where to return copy of part preceding `delim`. + * \param nr: Where to return value of numeric suffix`. + * \param name: String to split`. + * \param delim: Delimiter character`. + * \return Length of \a left. + */ size_t BLI_split_name_num(char *left, int *nr, const char *name, const char delim); bool BLI_string_is_decimal(const char *string) ATTR_NONNULL(); +/** + * Based on `BLI_split_dirfile()` / `os.path.splitext()`, + * `"a.b.c"` -> (`"a.b"`, `".c"`). + */ void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, const size_t str_len); +/** + * `"a.b.c"` -> (`"a."`, `"b.c"`). + */ void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, const size_t str_len); -/* Join strings, return newly allocated string. */ +/** + * Join strings, return newly allocated string. + */ char *BLI_string_join_array(char *result, size_t result_len, const char *strings[], uint strings_len) ATTR_NONNULL(); +/** + * A version of #BLI_string_join that takes a separator which can be any character including '\0'. + */ char *BLI_string_join_array_by_sep_char(char *result, size_t result_len, char sep, const char *strings[], uint strings_len) ATTR_NONNULL(); +/** + * Join an array of strings into a newly allocated, null terminated string. + */ char *BLI_string_join_arrayN(const char *strings[], uint strings_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * A version of #BLI_string_joinN that takes a separator which can be any character including '\0'. + */ char *BLI_string_join_array_by_sep_charN(char sep, const char *strings[], uint strings_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/** + * A version of #BLI_string_join_array_by_sep_charN that takes a table array. + * The new location of each string is written into this array. + */ char *BLI_string_join_array_by_sep_char_with_tableN(char sep, char *table[], const char *strings[], uint strings_len) ATTR_NONNULL(); -/* Take multiple arguments, pass as (array, length). */ +/** + * Take multiple arguments, pass as (array, length). + */ #define BLI_string_join(result, result_len, ...) \ BLI_string_join_array( \ result, result_len, ((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__)) @@ -75,17 +113,51 @@ char *BLI_string_join_array_by_sep_char_with_tableN(char sep, BLI_string_join_array_by_sep_char_with_tableN( \ sep, table, ((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__)) +/** + * Finds the best possible flipped (left/right) name. + * For renaming; check for unique names afterwards. + * + * \param r_name: flipped name, + * assumed to be a pointer to a string of at least \a name_len size. + * \param from_name: original name, + * assumed to be a pointer to a string of at least \a name_len size. + * \param strip_number: If set, remove number extensions. + * \return The number of bytes written into \a r_name. + */ size_t BLI_string_flip_side_name(char *r_name, const char *from_name, const bool strip_number, const size_t name_len); +/** + * Ensures name is unique (according to criteria specified by caller in unique_check callback), + * incrementing its numeric suffix as necessary. Returns true if name had to be adjusted. + * + * \param unique_check: Return true if name is not unique + * \param arg: Additional arg to unique_check--meaning is up to caller + * \param defname: To initialize name if latter is empty + * \param delim: Delimits numeric suffix in name + * \param name: Name to be ensured unique + * \param name_len: Maximum length of name area + * \return true if there if the name was changed + */ bool BLI_uniquename_cb(UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_len); +/** + * Ensures that the specified block has a unique name within the containing list, + * incrementing its numeric suffix as necessary. Returns true if name had to be adjusted. + * + * \param list: List containing the block + * \param vlink: The block to check the name for + * \param defname: To initialize block name if latter is empty + * \param delim: Delimits numeric suffix in name + * \param name_offset: Offset of name within block structure + * \param name_len: Maximum length of name area + */ bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h index 53ac5f7047b..73866815930 100644 --- a/source/blender/blenlib/BLI_task.h +++ b/source/blender/blenlib/BLI_task.h @@ -35,20 +35,24 @@ extern "C" { struct BLI_mempool; -/* Task Scheduler +/* -------------------------------------------------------------------- */ +/** \name Task Scheduler * - * Central scheduler that holds running threads ready to execute tasks. A single - * queue holds the task from all pools. + * Central scheduler that holds running threads ready to execute tasks. + * A single queue holds the task from all pools. * - * Init/exit must be called before/after any task pools are created/freed, and - * must be called from the main threads. All other scheduler and pool functions - * are thread-safe. */ + * Initialize/exit must be called before/after any task pools are created/freed, and must + * be called from the main threads. All other scheduler and pool functions are thread-safe. + * \{ */ void BLI_task_scheduler_init(void); void BLI_task_scheduler_exit(void); int BLI_task_scheduler_num_threads(void); -/* Task Pool +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Task Pool * * Pool of tasks that will be executed by the central task scheduler. For each * pool, we can wait for all tasks to be done, or cancel them before they are @@ -60,7 +64,7 @@ int BLI_task_scheduler_num_threads(void); * pool with smaller tasks. When other threads are busy they will continue * working on their own tasks, if not they will join in, no new threads will * be launched. - */ + * \{ */ typedef enum eTaskPriority { TASK_PRIORITY_LOW, @@ -71,25 +75,34 @@ typedef struct TaskPool TaskPool; typedef void (*TaskRunFunction)(TaskPool *__restrict pool, void *taskdata); typedef void (*TaskFreeFunction)(TaskPool *__restrict pool, void *taskdata); -/* Regular task pool that immediately starts executing tasks as soon as they - * are pushed, either on the current or another thread. */ +/** + * Regular task pool that immediately starts executing tasks as soon as they + * are pushed, either on the current or another thread. + */ TaskPool *BLI_task_pool_create(void *userdata, eTaskPriority priority); -/* Background: always run tasks in a background thread, never immediately - * execute them. For running background jobs. */ +/** + * Background: always run tasks in a background thread, never immediately + * execute them. For running background jobs. + */ TaskPool *BLI_task_pool_create_background(void *userdata, eTaskPriority priority); -/* Background Serial: run tasks one after the other in the background, - * without parallelization between the tasks. */ +/** + * Background Serial: run tasks one after the other in the background, + * without parallelization between the tasks. + */ TaskPool *BLI_task_pool_create_background_serial(void *userdata, eTaskPriority priority); -/* Suspended: don't execute tasks until work_and_wait is called. This is slower +/** + * Suspended: don't execute tasks until work_and_wait is called. This is slower * as threads can't immediately start working. But it can be used if the data - * structures the threads operate on are not fully initialized until all tasks - * are created. */ + * structures the threads operate on are not fully initialized until all tasks are created. + */ TaskPool *BLI_task_pool_create_suspended(void *userdata, eTaskPriority priority); -/* No threads: immediately executes tasks on the same thread. For debugging. */ +/** + * No threads: immediately executes tasks on the same thread. For debugging. + */ TaskPool *BLI_task_pool_create_no_threads(void *userdata); void BLI_task_pool_free(TaskPool *pool); @@ -100,28 +113,45 @@ void BLI_task_pool_push(TaskPool *pool, bool free_taskdata, TaskFreeFunction freedata); -/* work and wait until all tasks are done */ +/** + * Work and wait until all tasks are done. + */ void BLI_task_pool_work_and_wait(TaskPool *pool); -/* cancel all tasks, keep worker threads running */ +/** + * Cancel all tasks, keep worker threads running. + */ void BLI_task_pool_cancel(TaskPool *pool); -/* for worker threads, test if current task pool canceled. this function may +/** + * For worker threads, test if current task pool canceled. this function may * only be called from worker threads and pool must be the task pool that the - * thread is currently executing a task from. */ + * thread is currently executing a task from. + */ bool BLI_task_pool_current_canceled(TaskPool *pool); -/* optional userdata pointer to pass along to run function */ +/** + * Optional `userdata` pointer to pass along to run function. + */ void *BLI_task_pool_user_data(TaskPool *pool); -/* optional mutex to use from run function */ +/** + * Optional mutex to use from run function. + */ ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool); -/* Parallel for routines */ +/** \} */ -/* Per-thread specific data passed to the callback. */ +/* -------------------------------------------------------------------- */ +/** \name Parallel for Routines + * \{ */ + +/** + * Per-thread specific data passed to the callback. + */ typedef struct TaskParallelTLS { - /* Copy of user-specifier chunk, which is copied from original chunk to all - * worker threads. This is similar to OpenMP's firstprivate. + /** + * Copy of user-specifier chunk, which is copied from original chunk to all worker threads. + * This is similar to OpenMP's `firstprivate`. */ void *userdata_chunk; } TaskParallelTLS; @@ -186,7 +216,8 @@ void BLI_task_parallel_range(const int start, TaskParallelRangeFunc func, const TaskParallelSettings *settings); -/* This data is shared between all tasks, its access needs thread lock or similar protection. +/** + * This data is shared between all tasks, its access needs thread lock or similar protection. */ typedef struct TaskParallelIteratorStateShared { /* Maximum amount of items to acquire at once. */ @@ -222,6 +253,17 @@ void BLI_task_parallel_iterator(void *userdata, TaskParallelIteratorFunc func, const TaskParallelSettings *settings); +/** + * This function allows to parallelize for loops over ListBase items. + * + * \param listbase: The double linked list to loop over. + * \param userdata: Common userdata passed to all instances of \a func. + * \param func: Callback function. + * \param settings: See public API doc of ParallelRangeSettings for description of all settings. + * + * \note There is no static scheduling here, + * since it would need another full loop over items to count them. + */ void BLI_task_parallel_listbase(struct ListBase *listbase, void *userdata, TaskParallelIteratorFunc func, @@ -232,6 +274,16 @@ typedef struct MempoolIterData MempoolIterData; typedef void (*TaskParallelMempoolFunc)(void *userdata, MempoolIterData *iter, const TaskParallelTLS *__restrict tls); +/** + * This function allows to parallelize for loops over Mempool items. + * + * \param mempool: The iterable BLI_mempool to loop over. + * \param userdata: Common userdata passed to all instances of \a func. + * \param func: Callback function. + * \param settings: See public API doc of TaskParallelSettings for description of all settings. + * + * \note There is no static scheduling here. + */ void BLI_task_parallel_mempool(struct BLI_mempool *mempool, void *userdata, TaskParallelMempoolFunc func, @@ -252,14 +304,21 @@ BLI_INLINE void BLI_parallel_mempool_settings_defaults(TaskParallelSettings *set settings->use_threading = true; } -/* Don't use this, store any thread specific data in tls->userdata_chunk instead. - * Only here for code to be removed. */ +/** + * Don't use this, store any thread specific data in `tls->userdata_chunk` instead. + * Only here for code to be removed. + */ int BLI_task_parallel_thread_id(const TaskParallelTLS *tls); -/* Task Graph Scheduling */ -/* Task Graphs can be used to create a forest of directional trees and schedule work to any tree. +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Task Graph Scheduling + * + * Task Graphs can be used to create a forest of directional trees and schedule work to any tree. * The nodes in the graph can be run in separate threads. * + * \code{.unparsed} * +---- [root] ----+ * | | * v v @@ -267,55 +326,61 @@ int BLI_task_parallel_thread_id(const TaskParallelTLS *tls); * | | * v v * [node_3] [node_4] + * \endcode * - * TaskGraph *task_graph = BLI_task_graph_create(); - * TaskNode *root = BLI_task_graph_node_create(task_graph, root_exec, NULL, NULL); - * TaskNode *node_1 = BLI_task_graph_node_create(task_graph, node_exec, NULL, NULL); - * TaskNode *node_2 = BLI_task_graph_node_create(task_graph, node_exec, NULL, NULL); - * TaskNode *node_3 = BLI_task_graph_node_create(task_graph, node_exec, NULL, NULL); - * TaskNode *node_4 = BLI_task_graph_node_create(task_graph, node_exec, NULL, NULL); + * \code{.c} + * TaskGraph *task_graph = BLI_task_graph_create(); + * TaskNode *root = BLI_task_graph_node_create(task_graph, root_exec, NULL, NULL); + * TaskNode *node_1 = BLI_task_graph_node_create(task_graph, node_exec, NULL, NULL); + * TaskNode *node_2 = BLI_task_graph_node_create(task_graph, node_exec, NULL, NULL); + * TaskNode *node_3 = BLI_task_graph_node_create(task_graph, node_exec, NULL, NULL); + * TaskNode *node_4 = BLI_task_graph_node_create(task_graph, node_exec, NULL, NULL); * - * BLI_task_graph_edge_create(root, node_1); - * BLI_task_graph_edge_create(root, node_2); - * BLI_task_graph_edge_create(node_2, node_3); - * BLI_task_graph_edge_create(node_2, node_4); + * BLI_task_graph_edge_create(root, node_1); + * BLI_task_graph_edge_create(root, node_2); + * BLI_task_graph_edge_create(node_2, node_3); + * BLI_task_graph_edge_create(node_2, node_4); + * \endcode * * Any node can be triggered to start a chain of tasks. Normally you would trigger a root node but * it is supported to start the chain of tasks anywhere in the forest or tree. When a node * completes, the execution flow is forwarded via the created edges. * When a child node has multiple parents the child node will be triggered once for each parent. * - * BLI_task_graph_node_push_work(root); + * `BLI_task_graph_node_push_work(root);` * * In this example After `root` is finished, `node_1` and `node_2` will be started. * Only after `node_2` is finished `node_3` and `node_4` will be started. * * After scheduling work we need to wait until all the tasks have been finished. * - * BLI_task_graph_work_and_wait(); + * `BLI_task_graph_work_and_wait();` * * When finished you can clean up all the resources by freeing the task_graph. Nodes are owned by * the graph and are freed task_data will only be freed if a free_func was given. * - * BLI_task_graph_free(task_graph); + * `BLI_task_graph_free(task_graph);` * * Work can enter a tree on any node. Normally this would be the root_node. * A `task_graph` can be reused, but the caller needs to make sure the task_data is reset. * - * ** Task-Data ** + * Task-Data + * --------- * * Typically you want give a task data to work on. * Task data can be shared with other nodes, but be careful not to free the data multiple times. - * Task data is freed when calling `BLI_task_graph_free`. + * Task data is freed when calling #BLI_task_graph_free. * - * MyData *task_data = MEM_callocN(sizeof(MyData), __func__); - * TaskNode *root = BLI_task_graph_node_create(task_graph, root_exec, task_data, MEM_freeN); - * TaskNode *node_1 = BLI_task_graph_node_create(task_graph, node_exec, task_data, NULL); - * TaskNode *node_2 = BLI_task_graph_node_create(task_graph, node_exec, task_data, NULL); - * TaskNode *node_3 = BLI_task_graph_node_create(task_graph, node_exec, task_data, NULL); - * TaskNode *node_4 = BLI_task_graph_node_create(task_graph, node_exec, task_data, NULL); - * - */ + * \code{.c} + * MyData *task_data = MEM_callocN(sizeof(MyData), __func__); + * TaskNode *root = BLI_task_graph_node_create(task_graph, root_exec, task_data, MEM_freeN); + * TaskNode *node_1 = BLI_task_graph_node_create(task_graph, node_exec, task_data, NULL); + * TaskNode *node_2 = BLI_task_graph_node_create(task_graph, node_exec, task_data, NULL); + * TaskNode *node_3 = BLI_task_graph_node_create(task_graph, node_exec, task_data, NULL); + * TaskNode *node_4 = BLI_task_graph_node_create(task_graph, node_exec, task_data, NULL); + * \endcode + * \{ */ + struct TaskGraph; struct TaskNode; @@ -332,7 +397,10 @@ struct TaskNode *BLI_task_graph_node_create(struct TaskGraph *task_graph, bool BLI_task_graph_node_push_work(struct TaskNode *task_node); void BLI_task_graph_edge_create(struct TaskNode *from_node, struct TaskNode *to_node); -/* Task Isolation +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Task Isolation * * Task isolation helps avoid unexpected task scheduling decisions that can lead to bugs if wrong * assumptions were made. Typically that happens when doing "nested threading", i.e. one thread @@ -359,9 +427,12 @@ void BLI_task_graph_edge_create(struct TaskNode *from_node, struct TaskNode *to_ * multiple threads, another thread will typically run the task and avoid the deadlock. However, if * this situation happens on all threads at the same time, all threads will deadlock. This happened * in T88598. - */ + * \{ */ + void BLI_task_isolate(void (*func)(void *userdata), void *userdata); +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index 4f71e3aa6e4..6e60430ea38 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -38,12 +38,24 @@ struct ListBase; /* Threading API */ -/* This is run once at startup. */ +/** + * This is run once at startup. + */ void BLI_threadapi_init(void); void BLI_threadapi_exit(void); +/** + * \param tot: When 0 only initializes malloc mutex in a safe way (see sequence.c) + * problem otherwise: scene render will kill of the mutex! + */ void BLI_threadpool_init(struct ListBase *threadbase, void *(*do_thread)(void *), int tot); +/** + * Amount of available threads. + */ int BLI_available_threads(struct ListBase *threadbase); +/** + * Returns thread number, for sample patterns or threadsafe tables. + */ int BLI_threadpool_available_thread_index(struct ListBase *threadbase); void BLI_threadpool_insert(struct ListBase *threadbase, void *callerdata); void BLI_threadpool_remove(struct ListBase *threadbase, void *callerdata); @@ -54,7 +66,10 @@ int BLI_thread_is_main(void); /* System Information */ -int BLI_system_thread_count(void); /* gets the number of threads the system can make use of */ +/** + * \return the number of threads the system can make use of. + */ +int BLI_system_thread_count(void); void BLI_system_num_threads_override_set(int num); int BLI_system_num_threads_override_get(void); @@ -198,6 +213,7 @@ void BLI_thread_queue_nowait(ThreadQueue *queue); /* **** Special functions to help performance on crazy NUMA setups. **** */ /* Make sure process/thread is using NUMA node with fast memory access. */ + void BLI_thread_put_process_on_fast_node(void); void BLI_thread_put_thread_on_fast_node(void); diff --git a/source/blender/blenlib/BLI_timecode.h b/source/blender/blenlib/BLI_timecode.h index 5dfd9089598..768b9a896b0 100644 --- a/source/blender/blenlib/BLI_timecode.h +++ b/source/blender/blenlib/BLI_timecode.h @@ -29,6 +29,18 @@ extern "C" { #endif +/** + * Generate time-code/frame number string and store in \a str + * + * \param str: destination string + * \param maxncpy: maximum number of characters to copy `sizeof(str)` + * \param brevity_level: special setting for #View2D grid drawing, + * used to specify how detailed we need to be + * \param time_seconds: time total time in seconds + * \param fps: frames per second, typically from the #FPS macro + * \param timecode_style: enum from #eTimecodeStyles + * \return length of \a str + */ size_t BLI_timecode_string_from_time(char *str, const size_t maxncpy, const int brevity_level, @@ -36,10 +48,30 @@ size_t BLI_timecode_string_from_time(char *str, const double scene_fps, const short timecode_style) ATTR_NONNULL(); +/** + * Generate time string and store in \a str + * + * \param str: destination string + * \param maxncpy: maximum number of characters to copy `sizeof(str)` + * \param time_seconds: time total time in seconds + * \return length of \a str + */ size_t BLI_timecode_string_from_time_simple(char *str, const size_t maxncpy, const double time_seconds) ATTR_NONNULL(); +/** + * Generate time string and store in \a str + * + * \param str: destination string + * \param maxncpy: maximum number of characters to copy `sizeof(str)` + * \param brevity_level: special setting for #View2D grid drawing, + * used to specify how detailed we need to be + * \param time_seconds: time total time in seconds + * \return length of \a str + * + * \note in some cases this is used to print non-seconds values. + */ size_t BLI_timecode_string_from_time_seconds(char *str, const size_t maxncpy, const int brevity_level, diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index dec8acd7549..1b9457496ef 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -635,6 +635,9 @@ extern "C" { /* defined * in memory_utils.c for now. I do not know where we should put it actually... */ #ifndef __BLI_MEMORY_UTILS_H__ +/** + * Check if memory is zeroed, as with `memset(arr, 0, arr_size)`. + */ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size); #endif diff --git a/source/blender/blenlib/BLI_uvproject.h b/source/blender/blenlib/BLI_uvproject.h index 6028d95bda0..c1cc1cdbb51 100644 --- a/source/blender/blenlib/BLI_uvproject.h +++ b/source/blender/blenlib/BLI_uvproject.h @@ -26,16 +26,26 @@ extern "C" { struct Object; struct ProjCameraInfo; -/* create uv info from the camera, needs to be freed */ +/** + * Create UV info from the camera, needs to be freed. + * + * \param rotmat: can be `obedit->obmat` when uv project is used. + * \param winx, winy: can be from `scene->r.xsch / ysch`. + */ struct ProjCameraInfo *BLI_uvproject_camera_info(struct Object *ob, float rotmat[4][4], float winx, float winy); -/* apply uv from uvinfo (camera) */ +/** + * Apply UV from uvinfo (camera). + */ void BLI_uvproject_from_camera(float target[2], float source[3], struct ProjCameraInfo *uci); -/* apply uv from perspective matrix */ +/** + * Apply uv from perspective matrix. + * \param persmat: Can be `rv3d->persmat`. + */ void BLI_uvproject_from_view(float target[2], float source[3], float persmat[4][4], @@ -43,10 +53,14 @@ void BLI_uvproject_from_view(float target[2], float winx, float winy); -/* apply ortho uv's */ +/** + * Apply orthographic UV's. + */ void BLI_uvproject_from_view_ortho(float target[2], float source[3], const float rotmat[4][4]); -/* so we can adjust scale with keeping the struct private */ +/** + * So we can adjust scale with keeping the struct private. + */ void BLI_uvproject_camera_info_scale(struct ProjCameraInfo *uci, float scale_x, float scale_y); #ifdef __cplusplus diff --git a/source/blender/blenlib/BLI_voxel.h b/source/blender/blenlib/BLI_voxel.h index eb84f0a27ee..83e4bdbdc10 100644 --- a/source/blender/blenlib/BLI_voxel.h +++ b/source/blender/blenlib/BLI_voxel.h @@ -27,13 +27,13 @@ extern "C" { #endif -/** Find the index number of a voxel, given x/y/z integer coords and resolution vector. */ - +/** Calculate the index number of a voxel, given x/y/z integer coords and resolution vector. */ #define BLI_VOXEL_INDEX(x, y, z, res) \ ((int64_t)(x) + (int64_t)(y) * (int64_t)(res)[0] + \ (int64_t)(z) * (int64_t)(res)[0] * (int64_t)(res)[1]) -/* all input coordinates must be in bounding box 0.0 - 1.0 */ +/* All input coordinates must be in bounding box 0.0 - 1.0. */ + float BLI_voxel_sample_nearest(const float *data, const int res[3], const float co[3]); float BLI_voxel_sample_trilinear(const float *data, const int res[3], const float co[3]); float BLI_voxel_sample_triquadratic(const float *data, const int res[3], const float co[3]); diff --git a/source/blender/blenlib/intern/BLI_array.c b/source/blender/blenlib/intern/BLI_array.c index 7a9cf416d91..f4d60a9e047 100644 --- a/source/blender/blenlib/intern/BLI_array.c +++ b/source/blender/blenlib/intern/BLI_array.c @@ -54,11 +54,6 @@ #include "MEM_guardedalloc.h" -/** - * This function is only to be called via macros. - * - * \note The caller must adjust \a arr_len - */ void _bli_array_grow_func(void **arr_p, const void *arr_static, const int sizeof_arr_p, diff --git a/source/blender/blenlib/intern/BLI_assert.c b/source/blender/blenlib/intern/BLI_assert.c index cebc6f8957f..e089ef149a0 100644 --- a/source/blender/blenlib/intern/BLI_assert.c +++ b/source/blender/blenlib/intern/BLI_assert.c @@ -49,14 +49,13 @@ void _BLI_assert_print_backtrace(void) #endif } -/** - * Wrap to remove 'noreturn' attribute since this suppresses missing return statements, - * allowing changes to debug builds to accidentally to break release builds. - * - * For example `BLI_assert(0);` at the end of a function that returns a value, - * will hide that it's missing a return. - */ void _BLI_assert_abort(void) { + /* Wrap to remove 'noreturn' attribute since this suppresses missing return statements, + * allowing changes to debug builds to accidentally to break release builds. + * + * For example `BLI_assert(0);` at the end of a function that returns a value, + * will hide that it's missing a return. */ + abort(); } diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c index 8f7f722c71b..262d112d914 100644 --- a/source/blender/blenlib/intern/BLI_dynstr.c +++ b/source/blender/blenlib/intern/BLI_dynstr.c @@ -63,11 +63,6 @@ struct DynStr { /***/ -/** - * Create a new DynStr. - * - * \return Pointer to a new DynStr. - */ DynStr *BLI_dynstr_new(void) { DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr"); @@ -78,11 +73,6 @@ DynStr *BLI_dynstr_new(void) return ds; } -/** - * Create a new DynStr. - * - * \return Pointer to a new DynStr. - */ DynStr *BLI_dynstr_new_memarena(void) { DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr"); @@ -98,12 +88,6 @@ BLI_INLINE void *dynstr_alloc(DynStr *__restrict ds, size_t size) return ds->memarena ? BLI_memarena_alloc(ds->memarena, size) : malloc(size); } -/** - * Append a c-string to a DynStr. - * - * \param ds: The DynStr to append to. - * \param cstr: The c-string to append. - */ void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) { DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse)); @@ -123,13 +107,6 @@ void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ds->curlen += cstrlen; } -/** - * Append a length clamped c-string to a DynStr. - * - * \param ds: The DynStr to append to. - * \param cstr: The c-string to append. - * \param len: The maximum length of the c-string to copy. - */ void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len) { DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse)); @@ -209,12 +186,6 @@ void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format, v } } -/** - * Append a c-string to a DynStr, but with formatting like printf. - * - * \param ds: The DynStr to append to. - * \param format: The printf format string to use. - */ void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format, ...) { va_list args; @@ -277,25 +248,11 @@ void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format, .. } } -/** - * Find the length of a DynStr. - * - * \param ds: The DynStr of interest. - * \return The length of \a ds. - */ int BLI_dynstr_get_len(const DynStr *ds) { return ds->curlen; } -/** - * Get a DynStr's contents as a c-string. - * The \a rets argument must be allocated to be at - * least the size of `BLI_dynstr_get_len(ds) + 1`. - * - * \param ds: The DynStr of interest. - * \param rets: The string to fill. - */ void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets) { char *s; @@ -312,14 +269,6 @@ void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict ret rets[ds->curlen] = '\0'; } -/** - * Get a DynStr's contents as a c-string. - * <i> The returned c-string should be freed - * using MEM_freeN. </i> - * - * \param ds: The DynStr of interest. - * \return The contents of \a ds as a c-string. - */ char *BLI_dynstr_get_cstring(const DynStr *ds) { char *rets = MEM_mallocN(ds->curlen + 1, "dynstr_cstring"); @@ -327,11 +276,6 @@ char *BLI_dynstr_get_cstring(const DynStr *ds) return rets; } -/** - * Clear the DynStr - * - * \param ds: The DynStr to clear. - */ void BLI_dynstr_clear(DynStr *ds) { if (ds->memarena) { @@ -350,11 +294,6 @@ void BLI_dynstr_clear(DynStr *ds) ds->curlen = 0; } -/** - * Free the DynStr - * - * \param ds: The DynStr to free. - */ void BLI_dynstr_free(DynStr *ds) { if (ds->memarena) { diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c index f05dea46dc8..169f34f52c3 100644 --- a/source/blender/blenlib/intern/BLI_filelist.c +++ b/source/blender/blenlib/intern/BLI_filelist.c @@ -229,12 +229,6 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) } } -/** - * Scans the contents of the directory named *dirname, and allocates and fills in an - * array of entries describing them in *filelist. - * - * \return The length of filelist array. - */ unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist) { struct BuildDirCtx dir_ctx; @@ -256,9 +250,6 @@ unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_ return dir_ctx.nrfiles; } -/** - * Convert given entry's size into human-readable strings. - */ void BLI_filelist_entry_size_to_string(const struct stat *st, const uint64_t sz, /* Used to change MB -> M, etc. - is that really useful? */ @@ -278,9 +269,6 @@ void BLI_filelist_entry_size_to_string(const struct stat *st, #endif } -/** - * Convert given entry's modes into human-readable strings. - */ void BLI_filelist_entry_mode_to_string(const struct stat *st, const bool UNUSED(compact), char r_mode1[FILELIST_DIRENTRY_MODE_LEN], @@ -328,9 +316,6 @@ void BLI_filelist_entry_mode_to_string(const struct stat *st, #endif } -/** - * Convert given entry's owner into human-readable strings. - */ void BLI_filelist_entry_owner_to_string(const struct stat *st, const bool UNUSED(compact), char r_owner[FILELIST_DIRENTRY_OWNER_LEN]) @@ -349,12 +334,6 @@ void BLI_filelist_entry_owner_to_string(const struct stat *st, #endif } -/** - * Convert given entry's time into human-readable strings. - * - * \param r_is_today: optional, returns true if the date matches today's. - * \param r_is_yesterday: optional, returns true if the date matches yesterday's. - */ void BLI_filelist_entry_datetime_to_string(const struct stat *st, const int64_t ts, const bool compact, @@ -417,9 +396,6 @@ void BLI_filelist_entry_datetime_to_string(const struct stat *st, } } -/** - * Deep-duplicate of a single direntry. - */ void BLI_filelist_entry_duplicate(struct direntry *dst, const struct direntry *src) { *dst = *src; @@ -431,9 +407,6 @@ void BLI_filelist_entry_duplicate(struct direntry *dst, const struct direntry *s } } -/** - * Deep-duplicate of a #direntry array including the array itself. - */ void BLI_filelist_duplicate(struct direntry **dest_filelist, struct direntry *const src_filelist, const unsigned int nrentries) @@ -448,9 +421,6 @@ void BLI_filelist_duplicate(struct direntry **dest_filelist, } } -/** - * frees storage for a single direntry, not the direntry itself. - */ void BLI_filelist_entry_free(struct direntry *entry) { if (entry->relname) { @@ -461,9 +431,6 @@ void BLI_filelist_entry_free(struct direntry *entry) } } -/** - * Frees storage for an array of #direntry, including the array itself. - */ void BLI_filelist_free(struct direntry *filelist, const unsigned int nrentries) { unsigned int i; diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 2c9285e418a..859784222e4 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -694,16 +694,6 @@ static GHash *ghash_copy(const GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopy /** \name GHash Public API * \{ */ -/** - * Creates a new, empty GHash. - * - * \param hashfp: Hash callback. - * \param cmpfp: Comparison callback. - * \param info: Identifier string for the GHash. - * \param nentries_reserve: Optionally reserve the number of members that the hash will hold. - * Use this to avoid resizing buckets if the size is known or can be closely approximated. - * \return An empty GHash. - */ GHash *BLI_ghash_new_ex(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, @@ -712,72 +702,38 @@ GHash *BLI_ghash_new_ex(GHashHashFP hashfp, return ghash_new(hashfp, cmpfp, info, nentries_reserve, 0); } -/** - * Wraps #BLI_ghash_new_ex with zero entries reserved. - */ GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) { return BLI_ghash_new_ex(hashfp, cmpfp, info, 0); } -/** - * Copy given GHash. Keys and values are also copied if relevant callback is provided, - * else pointers remain the same. - */ GHash *BLI_ghash_copy(const GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp) { return ghash_copy(gh, keycopyfp, valcopyfp); } -/** - * Reserve given amount of entries (resize \a gh accordingly if needed). - */ void BLI_ghash_reserve(GHash *gh, const uint nentries_reserve) { ghash_buckets_expand(gh, nentries_reserve, true); ghash_buckets_contract(gh, nentries_reserve, true, false); } -/** - * \return size of the GHash. - */ uint BLI_ghash_len(const GHash *gh) { return gh->nentries; } -/** - * Insert a key/value pair into the \a gh. - * - * \note Duplicates are not checked, - * the caller is expected to ensure elements are unique unless - * GHASH_FLAG_ALLOW_DUPES flag is set. - */ void BLI_ghash_insert(GHash *gh, void *key, void *val) { ghash_insert(gh, key, val); } -/** - * Inserts a new value to a key that may already be in ghash. - * - * Avoids #BLI_ghash_remove, #BLI_ghash_insert calls (double lookups) - * - * \returns true if a new key has been added. - */ bool BLI_ghash_reinsert( GHash *gh, void *key, void *val, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) { return ghash_insert_safe(gh, key, val, true, keyfreefp, valfreefp); } -/** - * Replaces the key of an item in the \a gh. - * - * Use when a key is re-allocated or its memory location is changed. - * - * \returns The previous key or NULL if not found, the caller may free if it's needed. - */ void *BLI_ghash_replace_key(GHash *gh, void *key) { const uint hash = ghash_keyhash(gh, key); @@ -791,15 +747,6 @@ void *BLI_ghash_replace_key(GHash *gh, void *key) return NULL; } -/** - * Lookup the value of \a key in \a gh. - * - * \param key: The key to lookup. - * \returns the value for \a key or NULL. - * - * \note When NULL is a valid value, use #BLI_ghash_lookup_p to differentiate a missing key - * from a key with a NULL value. (Avoids calling #BLI_ghash_haskey before #BLI_ghash_lookup) - */ void *BLI_ghash_lookup(const GHash *gh, const void *key) { GHashEntry *e = (GHashEntry *)ghash_lookup_entry(gh, key); @@ -807,9 +754,6 @@ void *BLI_ghash_lookup(const GHash *gh, const void *key) return e ? e->val : NULL; } -/** - * A version of #BLI_ghash_lookup which accepts a fallback argument. - */ void *BLI_ghash_lookup_default(const GHash *gh, const void *key, void *val_default) { GHashEntry *e = (GHashEntry *)ghash_lookup_entry(gh, key); @@ -817,16 +761,6 @@ void *BLI_ghash_lookup_default(const GHash *gh, const void *key, void *val_defau return e ? e->val : val_default; } -/** - * Lookup a pointer to the value of \a key in \a gh. - * - * \param key: The key to lookup. - * \returns the pointer to value for \a key or NULL. - * - * \note This has 2 main benefits over #BLI_ghash_lookup. - * - A NULL return always means that \a key isn't in \a gh. - * - The value can be modified in-place without further function calls (faster). - */ void **BLI_ghash_lookup_p(GHash *gh, const void *key) { GHashEntry *e = (GHashEntry *)ghash_lookup_entry(gh, key); @@ -834,20 +768,6 @@ void **BLI_ghash_lookup_p(GHash *gh, const void *key) return e ? &e->val : NULL; } -/** - * Ensure \a key is exists in \a gh. - * - * This handles the common situation where the caller needs ensure a key is added to \a gh, - * constructing a new value in the case the key isn't found. - * Otherwise use the existing value. - * - * Such situations typically incur multiple lookups, however this function - * avoids them by ensuring the key is added, - * returning a pointer to the value so it can be used or initialized by the caller. - * - * \returns true when the value didn't need to be added. - * (when false, the caller _must_ initialize the value). - */ bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) { const uint hash = ghash_keyhash(gh, key); @@ -864,12 +784,6 @@ bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) return haskey; } -/** - * A version of #BLI_ghash_ensure_p that allows caller to re-assign the key. - * Typically used when the key is to be duplicated. - * - * \warning Caller _must_ write to \a r_key when returning false. - */ bool BLI_ghash_ensure_p_ex(GHash *gh, const void *key, void ***r_key, void ***r_val) { const uint hash = ghash_keyhash(gh, key); @@ -889,14 +803,6 @@ bool BLI_ghash_ensure_p_ex(GHash *gh, const void *key, void ***r_key, void ***r_ return haskey; } -/** - * Remove \a key from \a gh, or return false if the key wasn't found. - * - * \param key: The key to remove. - * \param keyfreefp: Optional callback to free the key. - * \param valfreefp: Optional callback to free the value. - * \return true if \a key was removed from \a gh. - */ bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, @@ -912,17 +818,11 @@ bool BLI_ghash_remove(GHash *gh, return false; } -/* same as above but return the value, - * no free value argument since it will be returned */ -/** - * Remove \a key from \a gh, returning the value or NULL if the key wasn't found. - * - * \param key: The key to remove. - * \param keyfreefp: Optional callback to free the key. - * \return the value of \a key int \a gh or NULL. - */ void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp) { + /* Same as above but return the value, + * no free value argument since it will be returned. */ + const uint hash = ghash_keyhash(gh, key); const uint bucket_index = ghash_bucket_index(gh, hash); GHashEntry *e = (GHashEntry *)ghash_remove_ex(gh, key, keyfreefp, NULL, bucket_index); @@ -935,23 +835,11 @@ void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp) return NULL; } -/** - * \return true if the \a key is in \a gh. - */ bool BLI_ghash_haskey(const GHash *gh, const void *key) { return (ghash_lookup_entry(gh, key) != NULL); } -/** - * Remove a random entry from \a gh, returning true - * if a key/value pair could be removed, false otherwise. - * - * \param r_key: The removed key. - * \param r_val: The removed value. - * \param state: Used for efficient removal. - * \return true if there was something to pop, false if ghash was already empty. - */ bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val) { GHashEntry *e = (GHashEntry *)ghash_pop(gh, state); @@ -970,13 +858,6 @@ bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val) return false; } -/** - * Reset \a gh clearing all entries. - * - * \param keyfreefp: Optional callback to free the key. - * \param valfreefp: Optional callback to free the value. - * \param nentries_reserve: Optionally reserve the number of members that the hash will hold. - */ void BLI_ghash_clear_ex(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp, @@ -990,21 +871,11 @@ void BLI_ghash_clear_ex(GHash *gh, BLI_mempool_clear_ex(gh->entrypool, nentries_reserve ? (int)nentries_reserve : -1); } -/** - * Wraps #BLI_ghash_clear_ex with zero entries reserved. - */ void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) { BLI_ghash_clear_ex(gh, keyfreefp, valfreefp, 0); } -/** - * Frees the GHash and its members. - * - * \param gh: The GHash to free. - * \param keyfreefp: Optional callback to free the key. - * \param valfreefp: Optional callback to free the value. - */ void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) { BLI_assert((int)gh->nentries == BLI_mempool_len(gh->entrypool)); @@ -1017,17 +888,11 @@ void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreef MEM_freeN(gh); } -/** - * Sets a GHash flag. - */ void BLI_ghash_flag_set(GHash *gh, uint flag) { gh->flag |= flag; } -/** - * Clear a GHash flag. - */ void BLI_ghash_flag_clear(GHash *gh, uint flag) { gh->flag &= ~flag; @@ -1039,14 +904,6 @@ void BLI_ghash_flag_clear(GHash *gh, uint flag) /** \name GHash Iterator API * \{ */ -/** - * Create a new GHashIterator. The hash table must not be mutated - * while the iterator is in use, and the iterator will step exactly - * #BLI_ghash_len(gh) times before becoming done. - * - * \param gh: The GHash to iterate over. - * \return Pointer to a new iterator. - */ GHashIterator *BLI_ghashIterator_new(GHash *gh) { GHashIterator *ghi = MEM_mallocN(sizeof(*ghi), "ghash iterator"); @@ -1054,14 +911,6 @@ GHashIterator *BLI_ghashIterator_new(GHash *gh) return ghi; } -/** - * Init an already allocated GHashIterator. The hash table must not - * be mutated while the iterator is in use, and the iterator will - * step exactly #BLI_ghash_len(gh) times before becoming done. - * - * \param ghi: The GHashIterator to initialize. - * \param gh: The GHash to iterate over. - */ void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh) { ghi->gh = gh; @@ -1078,11 +927,6 @@ void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh) } } -/** - * Steps the iterator to the next index. - * - * \param ghi: The iterator. - */ void BLI_ghashIterator_step(GHashIterator *ghi) { if (ghi->curEntry) { @@ -1097,11 +941,6 @@ void BLI_ghashIterator_step(GHashIterator *ghi) } } -/** - * Free a GHashIterator. - * - * \param ghi: The iterator to free. - */ void BLI_ghashIterator_free(GHashIterator *ghi) { MEM_freeN(ghi); @@ -1110,10 +949,7 @@ void BLI_ghashIterator_free(GHashIterator *ghi) /** \} */ /* -------------------------------------------------------------------- */ -/** \name GSet Public API - * - * Use ghash API to give 'set' functionality - * \{ */ + GSet *BLI_gset_new_ex(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info, @@ -1127,9 +963,6 @@ GSet *BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) return BLI_gset_new_ex(hashfp, cmpfp, info, 0); } -/** - * Copy given GSet. Keys are also copied if callback is provided, else pointers remain the same. - */ GSet *BLI_gset_copy(const GSet *gs, GHashKeyCopyFP keycopyfp) { return (GSet *)ghash_copy((const GHash *)gs, keycopyfp, NULL); @@ -1140,10 +973,6 @@ uint BLI_gset_len(const GSet *gs) return ((GHash *)gs)->nentries; } -/** - * Adds the key to the set (no checks for unique keys!). - * Matching #BLI_ghash_insert - */ void BLI_gset_insert(GSet *gs, void *key) { const uint hash = ghash_keyhash((GHash *)gs, key); @@ -1151,23 +980,11 @@ void BLI_gset_insert(GSet *gs, void *key) ghash_insert_ex_keyonly((GHash *)gs, key, bucket_index); } -/** - * A version of BLI_gset_insert which checks first if the key is in the set. - * \returns true if a new key has been added. - * - * \note GHash has no equivalent to this because typically the value would be different. - */ bool BLI_gset_add(GSet *gs, void *key) { return ghash_insert_safe_keyonly((GHash *)gs, key, false, NULL); } -/** - * Set counterpart to #BLI_ghash_ensure_p_ex. - * similar to BLI_gset_add, except it returns the key pointer. - * - * \warning Caller _must_ write to \a r_key when returning false. - */ bool BLI_gset_ensure_p_ex(GSet *gs, const void *key, void ***r_key) { const uint hash = ghash_keyhash((GHash *)gs, key); @@ -1186,23 +1003,11 @@ bool BLI_gset_ensure_p_ex(GSet *gs, const void *key, void ***r_key) return haskey; } -/** - * Adds the key to the set (duplicates are managed). - * Matching #BLI_ghash_reinsert - * - * \returns true if a new key has been added. - */ bool BLI_gset_reinsert(GSet *gs, void *key, GSetKeyFreeFP keyfreefp) { return ghash_insert_safe_keyonly((GHash *)gs, key, true, keyfreefp); } -/** - * Replaces the key to the set if it's found. - * Matching #BLI_ghash_replace_key - * - * \returns The old key or NULL if not found. - */ void *BLI_gset_replace_key(GSet *gs, void *key) { return BLI_ghash_replace_key((GHash *)gs, key); @@ -1218,13 +1023,6 @@ bool BLI_gset_haskey(const GSet *gs, const void *key) return (ghash_lookup_entry((const GHash *)gs, key) != NULL); } -/** - * Remove a random entry from \a gs, returning true if a key could be removed, false otherwise. - * - * \param r_key: The removed key. - * \param state: Used for efficient removal. - * \return true if there was something to pop, false if gset was already empty. - */ bool BLI_gset_pop(GSet *gs, GSetIterState *state, void **r_key) { GSetEntry *e = (GSetEntry *)ghash_pop((GHash *)gs, (GHashIterState *)state); @@ -1274,19 +1072,12 @@ void BLI_gset_flag_clear(GSet *gs, uint flag) * This can be useful when the key references data stored outside the GSet. * \{ */ -/** - * Returns the pointer to the key if it's found. - */ void *BLI_gset_lookup(const GSet *gs, const void *key) { Entry *e = ghash_lookup_entry((const GHash *)gs, key); return e ? e->key : NULL; } -/** - * Returns the pointer to the key if it's found, removing it from the GSet. - * \note Caller must handle freeing. - */ void *BLI_gset_pop_key(GSet *gs, const void *key) { const uint hash = ghash_keyhash((GHash *)gs, key); @@ -1308,9 +1099,6 @@ void *BLI_gset_pop_key(GSet *gs, const void *key) #include "BLI_math.h" -/** - * \return number of buckets in the GHash. - */ int BLI_ghash_buckets_len(const GHash *gh) { return (int)gh->nbuckets; @@ -1320,13 +1108,6 @@ int BLI_gset_buckets_len(const GSet *gs) return BLI_ghash_buckets_len((const GHash *)gs); } -/** - * Measure how well the hash function performs (1.0 is approx as good as random distribution), - * and return a few other stats like load, - * variance of the distribution of the entries in the buckets, etc. - * - * Smaller is better! - */ double BLI_ghash_calc_quality_ex(GHash *gh, double *r_load, double *r_variance, diff --git a/source/blender/blenlib/intern/BLI_ghash_utils.c b/source/blender/blenlib/intern/BLI_ghash_utils.c index b9144009304..f8e621e406c 100644 --- a/source/blender/blenlib/intern/BLI_ghash_utils.c +++ b/source/blender/blenlib/intern/BLI_ghash_utils.c @@ -46,9 +46,10 @@ uint BLI_ghashutil_ptrhash(const void *key) return (uint)(intptr_t)key; } #else -/* Based Python3.7's pointer hashing function. */ uint BLI_ghashutil_ptrhash(const void *key) { + /* Based Python3.7's pointer hashing function. */ + size_t y = (size_t)key; /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid * excessive hash collisions for dicts and sets */ @@ -134,15 +135,6 @@ size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b) return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2)); } -/** - * This function implements the widely used "djb" hash apparently posted - * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit - * unsigned hash value starts at 5381 and for each byte 'c' in the - * string, is updated: `hash = hash * 33 + c`. - * This function uses the signed value of each byte. - * - * NOTE: this is the same hash method that glib 2.34.0 uses. - */ uint BLI_ghashutil_strhash_n(const char *key, size_t n) { const signed char *p; diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index a221820d4c4..efa0110ed53 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -193,11 +193,6 @@ static void heap_node_free(Heap *heap, HeapNode *node) /** \name Public Heap API * \{ */ -/** - * Creates a new heap. Removed nodes are recycled, so memory usage will not shrink. - * - * \note Use when the size of the heap is known in advance. - */ Heap *BLI_heap_new_ex(uint tot_reserve) { Heap *heap = MEM_mallocN(sizeof(Heap), __func__); @@ -261,10 +256,6 @@ void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp) heap->nodes.free = NULL; } -/** - * Insert heap node with a value (often a 'cost') and pointer into the heap, - * duplicate values are allowed. - */ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) { HeapNode *node; @@ -289,9 +280,6 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) return node; } -/** - * Convenience function since this is a common pattern. - */ void BLI_heap_insert_or_update(Heap *heap, HeapNode **node_p, float value, void *ptr) { if (*node_p == NULL) { @@ -312,19 +300,11 @@ uint BLI_heap_len(const Heap *heap) return heap->size; } -/** - * Return the top node of the heap. - * This is the node with the lowest value. - */ HeapNode *BLI_heap_top(const Heap *heap) { return heap->tree[0]; } -/** - * Return the value of top node of the heap. - * This is the node with the lowest value. - */ float BLI_heap_top_value(const Heap *heap) { BLI_assert(heap->size != 0); @@ -332,9 +312,6 @@ float BLI_heap_top_value(const Heap *heap) return heap->tree[0]->value; } -/** - * Pop the top node off the heap and return its pointer. - */ void *BLI_heap_pop_min(Heap *heap) { BLI_assert(heap->size != 0); @@ -366,11 +343,6 @@ void BLI_heap_remove(Heap *heap, HeapNode *node) BLI_heap_pop_min(heap); } -/** - * Can be used to avoid #BLI_heap_remove, #BLI_heap_insert calls, - * balancing the tree still has a performance cost, - * but is often much less than remove/insert, difference is most noticeable with large heaps. - */ void BLI_heap_node_value_update(Heap *heap, HeapNode *node, float value) { if (value < node->value) { @@ -427,9 +399,6 @@ static bool heap_is_minheap(const Heap *heap, uint root) } return true; } -/** - * Only for checking internal errors (gtest). - */ bool BLI_heap_is_valid(const Heap *heap) { return heap_is_minheap(heap, 0); diff --git a/source/blender/blenlib/intern/BLI_heap_simple.c b/source/blender/blenlib/intern/BLI_heap_simple.c index c075a2f8643..f285dd074c3 100644 --- a/source/blender/blenlib/intern/BLI_heap_simple.c +++ b/source/blender/blenlib/intern/BLI_heap_simple.c @@ -147,11 +147,6 @@ static void heapsimple_up(HeapSimple *heap, uint i, float active_val, void *acti /** \name Public HeapSimple API * \{ */ -/** - * Creates a new simple heap, which only supports insertion and removal from top. - * - * \note Use when the size of the heap is known in advance. - */ HeapSimple *BLI_heapsimple_new_ex(uint tot_reserve) { HeapSimple *heap = MEM_mallocN(sizeof(HeapSimple), __func__); @@ -190,10 +185,6 @@ void BLI_heapsimple_clear(HeapSimple *heap, HeapSimpleFreeFP ptrfreefp) heap->size = 0; } -/** - * Insert heap node with a value (often a 'cost') and pointer into the heap, - * duplicate values are allowed. - */ void BLI_heapsimple_insert(HeapSimple *heap, float value, void *ptr) { if (UNLIKELY(heap->size >= heap->bufsize)) { @@ -214,9 +205,6 @@ uint BLI_heapsimple_len(const HeapSimple *heap) return heap->size; } -/** - * Return the lowest value of the heap. - */ float BLI_heapsimple_top_value(const HeapSimple *heap) { BLI_assert(heap->size != 0); @@ -224,9 +212,6 @@ float BLI_heapsimple_top_value(const HeapSimple *heap) return heap->tree[0].value; } -/** - * Pop the top node off the heap and return its pointer. - */ void *BLI_heapsimple_pop_min(HeapSimple *heap) { BLI_assert(heap->size != 0); diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 674654c99a8..64c2ce2a4a3 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -867,9 +867,6 @@ static void non_recursive_bvh_div_nodes(const BVHTree *tree, /** \name BLI_bvhtree API * \{ */ -/** - * \note many callers don't check for `NULL` return. - */ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis) { BVHTree *tree; @@ -1013,7 +1010,6 @@ void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoin bvhtree_node_inflate(tree, node, tree->epsilon); } -/* call before BLI_bvhtree_update_tree() */ bool BLI_bvhtree_update_node( BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints) { @@ -1038,9 +1034,6 @@ bool BLI_bvhtree_update_node( return true; } -/** - * Call #BLI_bvhtree_update_node() first for every node/point/triangle. - */ void BLI_bvhtree_update_tree(BVHTree *tree) { /* Update bottom=>top @@ -1054,18 +1047,11 @@ void BLI_bvhtree_update_tree(BVHTree *tree) node_join(tree, *index); } } -/** - * Number of times #BLI_bvhtree_insert has been called. - * mainly useful for asserts functions to check we added the correct number. - */ int BLI_bvhtree_get_len(const BVHTree *tree) { return tree->totleaf; } -/** - * Maximum number of children that a node can have. - */ int BLI_bvhtree_get_tree_type(const BVHTree *tree) { return tree->tree_type; @@ -1076,9 +1062,6 @@ float BLI_bvhtree_get_epsilon(const BVHTree *tree) return tree->epsilon; } -/** - * This function returns the bounding box of the BVH tree. - */ void BLI_bvhtree_get_bounding_box(BVHTree *tree, float r_bb_min[3], float r_bb_max[3]) { BVHNode *root = tree->nodes[tree->totleaf]; @@ -1264,11 +1247,6 @@ static bool tree_overlap_traverse_num(BVHOverlapData_Thread *data_thread, return false; } -/** - * Use to check the total number of threads #BLI_bvhtree_overlap will use. - * - * \warning Must be the first tree passed to #BLI_bvhtree_overlap! - */ int BLI_bvhtree_overlap_thread_num(const BVHTree *tree) { return (int)MIN2(tree->tree_type, tree->nodes[tree->totleaf]->totnode); @@ -1717,10 +1695,6 @@ static bool dfs_find_duplicate_fast_dfs(BVHNearestData *data, BVHNode *node) return false; } -/** - * Find the first node nearby. - * Favors speed over quality since it doesn't find the best target node. - */ int BLI_bvhtree_find_nearest_first(BVHTree *tree, const float co[3], const float dist_sq, @@ -2020,15 +1994,6 @@ float BLI_bvhtree_bb_raycast(const float bv[6], return dist; } -/** - * Calls the callback for every ray intersection - * - * \note Using a \a callback which resets or never sets the #BVHTreeRayHit index & dist works too, - * however using this function means existing generic callbacks can be used from custom callbacks - * without having to handle resetting the hit beforehand. - * It also avoid redundant argument and return value which aren't meaningful - * when collecting multiple hits. - */ void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree, const float co[3], const float dir[3], @@ -2395,18 +2360,6 @@ static bool bvhtree_walk_dfs_recursive(BVHTree_WalkData *walk_data, const BVHNod return true; } -/** - * This is a generic function to perform a depth first search on the #BVHTree - * where the search order and nodes traversed depend on callbacks passed in. - * - * \param tree: Tree to walk. - * \param walk_parent_cb: Callback on a parents bound-box to test if it should be traversed. - * \param walk_leaf_cb: Callback to test leaf nodes, callback must store its own result, - * returning false exits early. - * \param walk_order_cb: Callback that indicates which direction to search, - * either from the node with the lower or higher K-DOP axis value. - * \param userdata: Argument passed to all callbacks. - */ void BLI_bvhtree_walk_dfs(BVHTree *tree, BVHTree_WalkParentCallback walk_parent_cb, BVHTree_WalkLeafCallback walk_leaf_cb, diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c index 4cac526088b..765d2f0be55 100644 --- a/source/blender/blenlib/intern/BLI_linklist.c +++ b/source/blender/blenlib/intern/BLI_linklist.c @@ -100,10 +100,6 @@ void BLI_linklist_reverse(LinkNode **listp) *listp = rhead; } -/** - * Move an item from its current position to a new one inside a single-linked list. - * Note *listp may be modified. - */ void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index) { LinkNode *lnk, *lnk_psrc = NULL, *lnk_pdst = NULL; @@ -171,9 +167,6 @@ void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index) } } -/** - * A version of prepend that takes the allocated link. - */ void BLI_linklist_prepend_nlink(LinkNode **listp, void *ptr, LinkNode *nlink) { nlink->link = ptr; @@ -199,9 +192,6 @@ void BLI_linklist_prepend_pool(LinkNode **listp, void *ptr, BLI_mempool *mempool BLI_linklist_prepend_nlink(listp, ptr, nlink); } -/** - * A version of append that takes the allocated link. - */ void BLI_linklist_append_nlink(LinkNodePair *list_pair, void *ptr, LinkNode *nlink) { nlink->link = ptr; diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c index 0ab27a5adad..f1fc3bba4ea 100644 --- a/source/blender/blenlib/intern/BLI_memarena.c +++ b/source/blender/blenlib/intern/BLI_memarena.c @@ -179,16 +179,6 @@ void *BLI_memarena_calloc(MemArena *ma, size_t size) return ptr; } -/** - * Transfer ownership of allocated blocks from `ma_src` into `ma_dst`, - * cleaning the contents of `ma_src`. - * - * \note Useful for multi-threaded tasks that need a thread-local #MemArena - * that is kept after the multi-threaded operation is completed. - * - * \note Avoid accumulating memory pools where possible - * as any unused memory in `ma_src` is wasted every merge. - */ void BLI_memarena_merge(MemArena *ma_dst, MemArena *ma_src) { /* Memory arenas must be compatible. */ @@ -231,10 +221,6 @@ void BLI_memarena_merge(MemArena *ma_dst, MemArena *ma_src) VALGRIND_CREATE_MEMPOOL(ma_src, 0, false); } -/** - * Clear for reuse, avoids re-allocation when an arena may - * otherwise be free'd and recreated. - */ void BLI_memarena_clear(MemArena *ma) { if (ma->bufs) { diff --git a/source/blender/blenlib/intern/BLI_memblock.c b/source/blender/blenlib/intern/BLI_memblock.c index 2fbdfbe8a95..4e9d68d92e4 100644 --- a/source/blender/blenlib/intern/BLI_memblock.c +++ b/source/blender/blenlib/intern/BLI_memblock.c @@ -99,8 +99,6 @@ void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) MEM_freeN(mblk); } -/* Reset elem count to 0 but keep as much memory allocated needed for at least the previous elem - * count. */ void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback) { int elem_per_chunk = mblk->chunk_size / mblk->elem_size; @@ -191,9 +189,6 @@ void *BLI_memblock_iterstep(BLI_memblock_iter *iter) return ptr; } -/* Direct access. elem is element index inside the chosen chunk. - * Double usage: You can set chunk to 0 and set the absolute elem index. - * The correct chunk will be retrieve. */ void *BLI_memblock_elem_get(BLI_memblock *mblk, int chunk, int elem) { BLI_assert(chunk < mblk->chunk_len); diff --git a/source/blender/blenlib/intern/BLI_memiter.c b/source/blender/blenlib/intern/BLI_memiter.c index effbe5da5c4..98348fe2938 100644 --- a/source/blender/blenlib/intern/BLI_memiter.c +++ b/source/blender/blenlib/intern/BLI_memiter.c @@ -125,15 +125,6 @@ static void memiter_init(BLI_memiter *mi) /** \name Public API's * \{ */ -/** - * \param chunk_size_min: Should be a power of two and - * significantly larger than the average element size used. - * - * While allocations of any size are supported, they won't be efficient - * (effectively becoming a single-linked list). - * - * Its intended that many elements can be stored per chunk. - */ BLI_memiter *BLI_memiter_create(uint chunk_size_min) { BLI_memiter *mi = MEM_mallocN(sizeof(BLI_memiter), "BLI_memiter"); @@ -261,7 +252,6 @@ uint BLI_memiter_count(const BLI_memiter *mi) /** \name Helper API's * \{ */ -/* Support direct lookup for first. */ void *BLI_memiter_elem_first(BLI_memiter *mi) { if (mi->head != NULL) { diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c index bd6a124c7cb..df85d3e7553 100644 --- a/source/blender/blenlib/intern/BLI_mempool.c +++ b/source/blender/blenlib/intern/BLI_mempool.c @@ -367,11 +367,6 @@ void *BLI_mempool_calloc(BLI_mempool *pool) return retval; } -/** - * Free an element from the mempool. - * - * \note doesn't protect against double frees, take care! - */ void BLI_mempool_free(BLI_mempool *pool, void *addr) { BLI_freenode *newhead = addr; @@ -475,13 +470,6 @@ void *BLI_mempool_findelem(BLI_mempool *pool, uint index) return NULL; } -/** - * Fill in \a data with pointers to each element of the mempool, - * to create lookup table. - * - * \param pool: Pool to create a table from. - * \param data: array of pointers at least the size of 'pool->totused' - */ void BLI_mempool_as_table(BLI_mempool *pool, void **data) { BLI_mempool_iter iter; @@ -495,9 +483,6 @@ void BLI_mempool_as_table(BLI_mempool *pool, void **data) BLI_assert((uint)(p - data) == pool->totused); } -/** - * A version of #BLI_mempool_as_table that allocates and returns the data. - */ void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr) { void **data = MEM_mallocN((size_t)pool->totused * sizeof(void *), allocstr); @@ -505,9 +490,6 @@ void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr) return data; } -/** - * Fill in \a data with the contents of the mempool. - */ void BLI_mempool_as_array(BLI_mempool *pool, void *data) { const uint esize = pool->esize; @@ -522,9 +504,6 @@ void BLI_mempool_as_array(BLI_mempool *pool, void *data) BLI_assert((uint)(p - (char *)data) == pool->totused * esize); } -/** - * A version of #BLI_mempool_as_array that allocates and returns the data. - */ void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr) { char *data = MEM_malloc_arrayN(pool->totused, pool->esize, allocstr); @@ -532,9 +511,6 @@ void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr) return data; } -/** - * Initialize a new mempool iterator, #BLI_MEMPOOL_ALLOW_ITER flag must be set. - */ void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter) { BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER); @@ -550,19 +526,6 @@ static void mempool_threadsafe_iternew(BLI_mempool *pool, BLI_mempool_threadsafe ts_iter->curchunk_threaded_shared = NULL; } -/** - * Initialize an array of mempool iterators, #BLI_MEMPOOL_ALLOW_ITER flag must be set. - * - * This is used in threaded code, to generate as much iterators as needed - * (each task should have its own), - * such that each iterator goes over its own single chunk, - * and only getting the next chunk to iterate over has to be - * protected against concurrency (which can be done in a lockless way). - * - * To be used when creating a task for each single item in the pool is totally overkill. - * - * See BLI_task_parallel_mempool implementation for detailed usage example. - */ ParallelMempoolTaskData *mempool_iter_threadsafe_create(BLI_mempool *pool, const size_t num_iter) { BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER); @@ -625,13 +588,8 @@ void *BLI_mempool_iterstep(BLI_mempool_iter *iter) return ret; } -#else - -/* optimized version of code above */ +#else /* Optimized version of code above. */ -/** - * Step over the iterator, returning the mempool item or NULL. - */ void *BLI_mempool_iterstep(BLI_mempool_iter *iter) { if (UNLIKELY(iter->curchunk == NULL)) { @@ -660,11 +618,6 @@ void *BLI_mempool_iterstep(BLI_mempool_iter *iter) return ret; } -/** - * A version of #BLI_mempool_iterstep that uses - * #BLI_mempool_threadsafe_iter.curchunk_threaded_shared for threaded iteration support. - * (threaded section noted in comments). - */ void *mempool_iter_threadsafe_step(BLI_mempool_threadsafe_iter *ts_iter) { BLI_mempool_iter *iter = &ts_iter->iter; @@ -710,12 +663,6 @@ void *mempool_iter_threadsafe_step(BLI_mempool_threadsafe_iter *ts_iter) #endif -/** - * Empty the pool, as if it were just created. - * - * \param pool: The pool to clear. - * \param totelem_reserve: Optionally reserve how many items should be kept from clearing. - */ void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve) { BLI_mempool_chunk *mpchunk; @@ -768,17 +715,11 @@ void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve) } } -/** - * Wrap #BLI_mempool_clear_ex with no reserve set. - */ void BLI_mempool_clear(BLI_mempool *pool) { BLI_mempool_clear_ex(pool, -1); } -/** - * Free the mempool its self (and all elements). - */ void BLI_mempool_destroy(BLI_mempool *pool) { mempool_chunk_free_all(pool->chunks); diff --git a/source/blender/blenlib/intern/BLI_mempool_private.h b/source/blender/blenlib/intern/BLI_mempool_private.h index e1c8205c80c..1d18f6d1b28 100644 --- a/source/blender/blenlib/intern/BLI_mempool_private.h +++ b/source/blender/blenlib/intern/BLI_mempool_private.h @@ -41,10 +41,28 @@ typedef struct ParallelMempoolTaskData { TaskParallelTLS tls; } ParallelMempoolTaskData; +/** + * Initialize an array of mempool iterators, #BLI_MEMPOOL_ALLOW_ITER flag must be set. + * + * This is used in threaded code, to generate as much iterators as needed + * (each task should have its own), + * such that each iterator goes over its own single chunk, + * and only getting the next chunk to iterate over has to be + * protected against concurrency (which can be done in a lockless way). + * + * To be used when creating a task for each single item in the pool is totally overkill. + * + * See #BLI_task_parallel_mempool implementation for detailed usage example. + */ ParallelMempoolTaskData *mempool_iter_threadsafe_create(BLI_mempool *pool, const size_t num_iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void mempool_iter_threadsafe_destroy(ParallelMempoolTaskData *iter_arr) ATTR_NONNULL(); +/** + * A version of #BLI_mempool_iterstep that uses + * #BLI_mempool_threadsafe_iter.curchunk_threaded_shared for threaded iteration support. + * (threaded section noted in comments). + */ void *mempool_iter_threadsafe_step(BLI_mempool_threadsafe_iter *iter); #ifdef __cplusplus diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c index 436b9b8d782..66c394f5eb2 100644 --- a/source/blender/blenlib/intern/DLRB_tree.c +++ b/source/blender/blenlib/intern/DLRB_tree.c @@ -29,14 +29,12 @@ /* *********************************************** */ /* Tree API */ -/* Create a new tree, and initialize as necessary */ DLRBT_Tree *BLI_dlrbTree_new(void) { /* just allocate for now */ return MEM_callocN(sizeof(DLRBT_Tree), "DLRBT_Tree"); } -/* Just zero out the pointers used */ void BLI_dlrbTree_init(DLRBT_Tree *tree) { if (tree == NULL) { @@ -62,7 +60,6 @@ static void recursive_tree_free_nodes(DLRBT_Node *node) MEM_freeN(node); } -/* Free the given tree's data but not the tree itself */ void BLI_dlrbTree_free(DLRBT_Tree *tree) { if (tree == NULL) { @@ -109,7 +106,6 @@ static void linkedlist_sync_add_node(DLRBT_Tree *tree, DLRBT_Node *node) linkedlist_sync_add_node(tree, node->right); } -/* Make sure the tree's Double-Linked list representation is valid */ void BLI_dlrbTree_linkedlist_sync(DLRBT_Tree *tree) { /* sanity checks */ @@ -127,7 +123,6 @@ void BLI_dlrbTree_linkedlist_sync(DLRBT_Tree *tree) /* *********************************************** */ /* Tree Search Utilities */ -/* Find the node which matches or is the closest to the requested node */ DLRBT_Node *BLI_dlrbTree_search(const DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data) @@ -175,7 +170,6 @@ DLRBT_Node *BLI_dlrbTree_search(const DLRBT_Tree *tree, return node; } -/* Find the node which exactly matches the required data */ DLRBT_Node *BLI_dlrbTree_search_exact(const DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data) @@ -223,7 +217,6 @@ DLRBT_Node *BLI_dlrbTree_search_exact(const DLRBT_Tree *tree, return (found == 1) ? (node) : (NULL); } -/* Find the node which occurs immediately before the best matching node */ DLRBT_Node *BLI_dlrbTree_search_prev(const DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data) @@ -254,7 +247,6 @@ DLRBT_Node *BLI_dlrbTree_search_prev(const DLRBT_Tree *tree, return NULL; } -/* Find the node which occurs immediately after the best matching node */ DLRBT_Node *BLI_dlrbTree_search_next(const DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data) @@ -285,7 +277,6 @@ DLRBT_Node *BLI_dlrbTree_search_next(const DLRBT_Tree *tree, return NULL; } -/* Check whether there is a node matching the requested node */ short BLI_dlrbTree_contains(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data) { /* check if an exact search throws up anything... */ @@ -522,9 +513,6 @@ static void insert_check_3(DLRBT_Tree *tree, DLRBT_Node *node) /* ----- */ -/* Balance the tree after the given element has been added to it - * (using custom code, in the Binary Tree way). - */ void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node) { /* sanity checks */ @@ -541,9 +529,6 @@ void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node) /* ----- */ -/* Add the given data to the tree, and return the node added */ -/* NOTE: for duplicates, the update_cb is called (if available), - * and the existing node is returned */ DLRBT_Node *BLI_dlrbTree_add(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, DLRBT_NAlloc_FP new_cb, diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index ee06d8b6347..08696c9168d 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -1399,26 +1399,6 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info, /** \name Main Array Storage API * \{ */ -/** - * Create a new array store, which can store any number of arrays - * as long as their stride matches. - * - * \param stride: `sizeof()` each element, - * - * \note while a stride of `1` will always work, - * its less efficient since duplicate chunks of memory will be searched - * at positions unaligned with the array data. - * - * \param chunk_count: Number of elements to split each chunk into. - * - A small value increases the ability to de-duplicate chunks, - * but adds overhead by increasing the number of chunks to look up when searching for duplicates, - * as well as some overhead constructing the original array again, with more calls to `memcpy`. - * - Larger values reduce the *book keeping* overhead, - * but increase the chance a small, - * isolated change will cause a larger amount of data to be duplicated. - * - * \return A new array store, to be freed with #BLI_array_store_destroy. - */ BArrayStore *BLI_array_store_create(uint stride, uint chunk_count) { BArrayStore *bs = MEM_callocN(sizeof(BArrayStore), __func__); @@ -1472,9 +1452,6 @@ static void array_store_free_data(BArrayStore *bs) } } -/** - * Free the #BArrayStore, including all states and chunks. - */ void BLI_array_store_destroy(BArrayStore *bs) { array_store_free_data(bs); @@ -1486,9 +1463,6 @@ void BLI_array_store_destroy(BArrayStore *bs) MEM_freeN(bs); } -/** - * Clear all contents, allowing reuse of \a bs. - */ void BLI_array_store_clear(BArrayStore *bs) { array_store_free_data(bs); @@ -1506,9 +1480,6 @@ void BLI_array_store_clear(BArrayStore *bs) /** \name BArrayStore Statistics * \{ */ -/** - * \return the total amount of memory that would be used by getting the arrays for all states. - */ size_t BLI_array_store_calc_size_expanded_get(const BArrayStore *bs) { size_t size_accum = 0; @@ -1518,10 +1489,6 @@ size_t BLI_array_store_calc_size_expanded_get(const BArrayStore *bs) return size_accum; } -/** - * \return the amount of memory used by all #BChunk.data - * (duplicate chunks are only counted once). - */ size_t BLI_array_store_calc_size_compacted_get(const BArrayStore *bs) { size_t size_total = 0; @@ -1541,18 +1508,6 @@ size_t BLI_array_store_calc_size_compacted_get(const BArrayStore *bs) /** \name BArrayState Access * \{ */ -/** - * - * \param data: Data used to create - * \param state_reference: The state to use as a reference when adding the new state, - * typically this is the previous state, - * however it can be any previously created state from this \a bs. - * - * \return The new state, - * which is used by the caller as a handle to get back the contents of \a data. - * This may be removed using #BLI_array_store_state_remove, - * otherwise it will be removed with #BLI_array_store_destroy. - */ BArrayState *BLI_array_store_state_add(BArrayStore *bs, const void *data, const size_t data_len, @@ -1601,11 +1556,6 @@ BArrayState *BLI_array_store_state_add(BArrayStore *bs, return state; } -/** - * Remove a state and free any unused #BChunk data. - * - * The states can be freed in any order. - */ void BLI_array_store_state_remove(BArrayStore *bs, BArrayState *state) { #ifdef USE_PARANOID_CHECKS @@ -1618,18 +1568,11 @@ void BLI_array_store_state_remove(BArrayStore *bs, BArrayState *state) MEM_freeN(state); } -/** - * \return the expanded size of the array, - * use this to know how much memory to allocate #BLI_array_store_state_data_get's argument. - */ size_t BLI_array_store_state_size_get(BArrayState *state) { return state->chunk_list->total_size; } -/** - * Fill in existing allocated memory with the contents of \a state. - */ void BLI_array_store_state_data_get(BArrayState *state, void *data) { #ifdef USE_PARANOID_CHECKS @@ -1648,9 +1591,6 @@ void BLI_array_store_state_data_get(BArrayState *state, void *data) } } -/** - * Allocate an array for \a state and return it. - */ void *BLI_array_store_state_data_get_alloc(BArrayState *state, size_t *r_data_len) { void *data = MEM_mallocN(state->chunk_list->total_size, __func__); diff --git a/source/blender/blenlib/intern/array_utils.c b/source/blender/blenlib/intern/array_utils.c index 9a12a7442b7..36bd193810e 100644 --- a/source/blender/blenlib/intern/array_utils.c +++ b/source/blender/blenlib/intern/array_utils.c @@ -35,11 +35,6 @@ #include "BLI_array_utils.h" -/** - *In-place array reverse. - * - * Access via #BLI_array_reverse - */ void _bli_array_reverse(void *arr_v, uint arr_len, size_t arr_stride) { const uint arr_stride_uint = (uint)arr_stride; @@ -56,12 +51,6 @@ void _bli_array_reverse(void *arr_v, uint arr_len, size_t arr_stride) } } -/** - * In-place array wrap. - * (rotate the array one step forward or backwards). - * - * Access via #BLI_array_wrap - */ void _bli_array_wrap(void *arr_v, uint arr_len, size_t arr_stride, int dir) { char *arr = arr_v; @@ -82,12 +71,6 @@ void _bli_array_wrap(void *arr_v, uint arr_len, size_t arr_stride, int dir) } } -/** - *In-place array permute. - * (re-arrange elements based on an array of indices). - * - * Access via #BLI_array_wrap - */ void _bli_array_permute( void *arr, const uint arr_len, const size_t arr_stride, const uint *order, void *arr_temp) { @@ -117,13 +100,6 @@ void _bli_array_permute( } } -/** - * In-place array de-duplication of an ordered array. - * - * \return The new length of the array. - * - * Access via #BLI_array_deduplicate_ordered - */ uint _bli_array_deduplicate_ordered(void *arr, uint arr_len, size_t arr_stride) { if (UNLIKELY(arr_len <= 1)) { @@ -146,13 +122,6 @@ uint _bli_array_deduplicate_ordered(void *arr, uint arr_len, size_t arr_stride) return j + 1; } -/** - * Find the first index of an item in an array. - * - * Access via #BLI_array_findindex - * - * \note Not efficient, use for error checks/asserts. - */ int _bli_array_findindex(const void *arr, uint arr_len, size_t arr_stride, const void *p) { const char *arr_step = (const char *)arr; @@ -164,9 +133,6 @@ int _bli_array_findindex(const void *arr, uint arr_len, size_t arr_stride, const return -1; } -/** - * A version of #BLI_array_findindex that searches from the end of the list. - */ int _bli_array_rfindindex(const void *arr, uint arr_len, size_t arr_stride, const void *p) { const char *arr_step = (const char *)arr + (arr_stride * arr_len); @@ -205,22 +171,6 @@ void _bli_array_binary_or( } } -/** - * Utility function to iterate over contiguous items in an array. - * - * \param use_wrap: Detect contiguous ranges across the first/last points. - * In this case the second index of \a span_step may be lower than the first, - * which indicates the values are wrapped. - * \param use_delimit_bounds: When false, - * ranges that defined by the start/end indices are excluded. - * This option has no effect when \a use_wrap is enabled. - * \param test_fn: Function to test if the item should be included in the range. - * \param user_data: User data for \a test_fn. - * \param span_step: Indices to iterate over, - * initialize both values to the array length to initialize iteration. - * \param r_span_len: The length of the span, useful when \a use_wrap is enabled, - * where calculating the length isn't a simple subtraction. - */ bool _bli_array_iter_span(const void *arr, uint arr_len, size_t arr_stride, @@ -330,9 +280,6 @@ bool _bli_array_iter_span(const void *arr, return false; } -/** - * Simple utility to check memory is zeroed. - */ bool _bli_array_is_zeroed(const void *arr_v, uint arr_len, size_t arr_stride) { const char *arr_step = (const char *)arr_v; @@ -345,13 +292,6 @@ bool _bli_array_is_zeroed(const void *arr_v, uint arr_len, size_t arr_stride) return true; } -/** - * Smart function to sample a rect spiraling outside. - * Nice for selection ID. - * - * \param arr_shape: dimensions [w, h]. - * \param center: coordinates [x, y] indicating where to start traversing. - */ bool _bli_array_iter_spiral_square(const void *arr_v, const int arr_shape[2], size_t elem_size, diff --git a/source/blender/blenlib/intern/astar.c b/source/blender/blenlib/intern/astar.c index 1f71a62d191..8347e00adc8 100644 --- a/source/blender/blenlib/intern/astar.c +++ b/source/blender/blenlib/intern/astar.c @@ -53,25 +53,11 @@ #include "BLI_astar.h" -/** - * Init a node in A* graph. - * - * \param custom_data: an opaque pointer attached to this link, - * available e.g. to cost callback function. - */ void BLI_astar_node_init(BLI_AStarGraph *as_graph, const int node_index, void *custom_data) { as_graph->nodes[node_index].custom_data = custom_data; } -/** - * Add a link between two nodes of our A* graph. - * - * \param cost: the 'length' of the link - * (actual distance between two vertices or face centers e.g.). - * \param custom_data: an opaque pointer attached to this link, - * available e.g. to cost callback function. - */ void BLI_astar_node_link_add(BLI_AStarGraph *as_graph, const int node1_index, const int node2_index, @@ -93,22 +79,11 @@ void BLI_astar_node_link_add(BLI_AStarGraph *as_graph, BLI_addtail(&(as_graph->nodes[node2_index].neighbor_links), &ld[1]); } -/** - * \return The index of the other node of given link. - */ int BLI_astar_node_link_other_node(BLI_AStarGNLink *lnk, const int idx) { return (lnk->nodes[0] == idx) ? lnk->nodes[1] : lnk->nodes[0]; } -/** - * Initialize a solution data for given A* graph. Does not compute anything! - * - * \param custom_data: an opaque pointer attached to this link, available e.g - * . to cost callback function. - * - * \note BLI_AStarSolution stores nearly all data needed during solution compute. - */ void BLI_astar_solution_init(BLI_AStarGraph *as_graph, BLI_AStarSolution *as_solution, void *custom_data) @@ -133,12 +108,6 @@ void BLI_astar_solution_init(BLI_AStarGraph *as_graph, as_solution->g_steps = BLI_memarena_alloc(mem, sizeof(*as_solution->g_steps) * node_num); } -/** - * Clear given solution's data, but does not release its memory. Avoids having to recreate/allocate - * a memarena in loops, e.g. - * - * \note This *has to be called* between each path solving. - */ void BLI_astar_solution_clear(BLI_AStarSolution *as_solution) { if (as_solution->mem) { @@ -156,9 +125,6 @@ void BLI_astar_solution_clear(BLI_AStarSolution *as_solution) as_solution->g_steps = NULL; } -/** - * Release the memory allocated for this solution. - */ void BLI_astar_solution_free(BLI_AStarSolution *as_solution) { if (as_solution->mem) { @@ -167,14 +133,6 @@ void BLI_astar_solution_free(BLI_AStarSolution *as_solution) } } -/** - * Init an A* graph. Total number of nodes must be known. - * - * Nodes might be e.g. vertices, faces, ... - * - * \param custom_data: an opaque pointer attached to this link, - * available e.g. to cost callback function. - */ void BLI_astar_graph_init(BLI_AStarGraph *as_graph, const int node_num, void *custom_data) { MemArena *mem = as_graph->mem; @@ -199,14 +157,6 @@ void BLI_astar_graph_free(BLI_AStarGraph *as_graph) } } -/** - * Solve a path in given graph, using given 'cost' callback function. - * - * \param max_steps: maximum number of nodes the found path may have. - * Useful in performance-critical usages. - * If no path is found within given steps, returns false too. - * \return true if a path was found, false otherwise. - */ bool BLI_astar_graph_solve(BLI_AStarGraph *as_graph, const int node_index_src, const int node_index_dst, diff --git a/source/blender/blenlib/intern/bitmap.c b/source/blender/blenlib/intern/bitmap.c index 54edcaec2c8..681736b7927 100644 --- a/source/blender/blenlib/intern/bitmap.c +++ b/source/blender/blenlib/intern/bitmap.c @@ -29,13 +29,11 @@ #include "BLI_bitmap.h" #include "BLI_utildefines.h" -/** Set or clear all bits in the bitmap. */ void BLI_bitmap_set_all(BLI_bitmap *bitmap, bool set, size_t bits) { memset(bitmap, set ? UCHAR_MAX : 0, BLI_BITMAP_SIZE(bits)); } -/** Invert all bits in the bitmap. */ void BLI_bitmap_flip_all(BLI_bitmap *bitmap, size_t bits) { size_t num_blocks = _BITMAP_NUM_BLOCKS(bits); @@ -44,13 +42,11 @@ void BLI_bitmap_flip_all(BLI_bitmap *bitmap, size_t bits) } } -/** Copy all bits from one bitmap to another. */ void BLI_bitmap_copy_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits) { memcpy(dst, src, BLI_BITMAP_SIZE(bits)); } -/** Combine two bitmaps with boolean AND. */ void BLI_bitmap_and_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits) { size_t num_blocks = _BITMAP_NUM_BLOCKS(bits); @@ -59,7 +55,6 @@ void BLI_bitmap_and_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits) } } -/** Combine two bitmaps with boolean OR. */ void BLI_bitmap_or_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits) { size_t num_blocks = _BITMAP_NUM_BLOCKS(bits); diff --git a/source/blender/blenlib/intern/bitmap_draw_2d.c b/source/blender/blenlib/intern/bitmap_draw_2d.c index b0afe1349ad..670ea75e9ea 100644 --- a/source/blender/blenlib/intern/bitmap_draw_2d.c +++ b/source/blender/blenlib/intern/bitmap_draw_2d.c @@ -41,11 +41,6 @@ /** \name Draw Line * \{ */ -/** - * Plot a line from \a p1 to \a p2 (inclusive). - * - * \note For clipped line drawing, see: http://stackoverflow.com/a/40902741/432509 - */ void BLI_bitmap_draw_2d_line_v2v2i(const int p1[2], const int p2[2], bool (*callback)(int, int, void *), @@ -223,9 +218,6 @@ static void draw_tri_flat_min(const int p[2], } } -/** - * \note Unclipped (clipped version can be added if needed). - */ void BLI_bitmap_draw_2d_tri_v2i( /* all 2d */ const int p1[2], @@ -338,18 +330,6 @@ static int draw_poly_v2i_n__span_y_sort(const void *a_p, const void *b_p, void * return 0; } -/** - * Draws a filled polygon with support for self intersections. - * - * \param callback: Takes the x, y coords and x-span (\a x_end is not inclusive), - * note that \a x_end will always be greater than \a x, so we can use: - * - * \code{.c} - * do { - * func(x, y); - * } while (++x != x_end); - * \endcode - */ void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin, const int ymin, const int xmax, diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c index cf5831cada5..85b7ba54406 100644 --- a/source/blender/blenlib/intern/boxpack_2d.c +++ b/source/blender/blenlib/intern/boxpack_2d.c @@ -277,20 +277,6 @@ static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p) } /** \} */ -/** - * Main box-packing function accessed from other functions - * This sets boxes x,y to positive values, sorting from 0,0 outwards. - * There is no limit to the space boxes may take, only that they will be packed - * tightly into the lower left hand corner (0,0) - * - * \param boxarray: a pre-allocated array of boxes. - * only the 'box->x' and 'box->y' are set, 'box->w' and 'box->h' are used, - * 'box->index' is not used at all, the only reason its there - * is that the box array is sorted by area and programs need to be able - * to have some way of writing the boxes back to the original data. - * \param len: the number of boxes in the array. - * \param r_tot_x, r_tot_y: set so you can normalize the data. - */ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r_tot_y) { uint box_index, verts_pack_len, i, j, k; @@ -678,18 +664,6 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r MEM_freeN(vs_ctx.vertarray); } -/* Packs boxes into a fixed area. - * boxes and packed are linked lists containing structs that can be cast to - * FixedSizeBoxPack (i.e. contains a FixedSizeBoxPack as its first element). - * Boxes that were packed successfully are placed into *packed and removed from *boxes. - * - * The algorithm is a simplified version of https://github.com/TeamHypersomnia/rectpack2D. - * Better ones could be used, but for the current use case (packing Image tiles into GPU - * textures) this is fine. - * - * Note that packing efficiency depends on the order of the input boxes. Generally speaking, - * larger boxes should come first, though how exactly size is best defined (e.g. area, - * perimeter) depends on the particular application. */ void BLI_box_pack_2d_fixedarea(ListBase *boxes, int width, int height, ListBase *packed) { ListBase spaces = {NULL}; diff --git a/source/blender/blenlib/intern/buffer.c b/source/blender/blenlib/intern/buffer.c index 74e97d89430..9df32051281 100644 --- a/source/blender/blenlib/intern/buffer.c +++ b/source/blender/blenlib/intern/buffer.c @@ -86,11 +86,6 @@ void BLI_buffer_resize(BLI_Buffer *buffer, const size_t new_count) buffer->count = new_count; } -/** - * Similar to #BLI_buffer_resize, but use when the existing data can be: - * - Ignored (malloc'd) - * - Cleared (when BLI_BUFFER_USE_CALLOC is set) - */ void BLI_buffer_reinit(BLI_Buffer *buffer, const size_t new_count) { if (UNLIKELY(new_count > buffer->alloc_count)) { @@ -114,7 +109,6 @@ void BLI_buffer_reinit(BLI_Buffer *buffer, const size_t new_count) buffer->count = new_count; } -/* Callers use BLI_buffer_append_array. */ void _bli_buffer_append_array(BLI_Buffer *buffer, void *new_data, size_t count) { size_t size = buffer->count; @@ -124,7 +118,6 @@ void _bli_buffer_append_array(BLI_Buffer *buffer, void *new_data, size_t count) memcpy(bytes + size * buffer->elem_size, new_data, count * buffer->elem_size); } -/* callers use BLI_buffer_free */ void _bli_buffer_free(BLI_Buffer *buffer) { if ((buffer->flag & BLI_BUFFER_USE_STATIC) == 0) { diff --git a/source/blender/blenlib/intern/convexhull_2d.c b/source/blender/blenlib/intern/convexhull_2d.c index 233a1430fe7..df675b512d9 100644 --- a/source/blender/blenlib/intern/convexhull_2d.c +++ b/source/blender/blenlib/intern/convexhull_2d.c @@ -53,14 +53,6 @@ static float is_left(const float p0[2], const float p1[2], const float p2[2]) return (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1]); } -/** - * A.M. Andrew's monotone chain 2D convex hull algorithm - * - * \param points: An array of 2D points presorted by increasing x and y-coords. - * \param n: The number of points in points. - * \param r_points: An array of the convex hull vertex indices (max is n). - * \returns the number of points in r_points. - */ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points[]) { /* the output array r_points[] will be used as the stack */ @@ -182,16 +174,6 @@ static int pointref_cmp_yx(const void *a_, const void *b_) return 0; } -/** - * A.M. Andrew's monotone chain 2D convex hull algorithm - * - * \param points: An array of 2D points. - * \param n: The number of points in points. - * \param r_points: An array of the convex hull vertex indices (max is n). - * _must_ be allocated as `n * 2` because of how its used internally, - * even though the final result will be no more than \a n in size. - * \returns the number of points in r_points. - */ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[]) { struct PointRef *points_ref = MEM_mallocN(sizeof(*points_ref) * (size_t)n, __func__); @@ -234,16 +216,6 @@ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[]) /** \name Utility Convex-Hull Functions * \{ */ -/** - * \return The best angle for fitting the convex hull to an axis aligned bounding box. - * - * Intended to be used with #BLI_convexhull_2d - * - * \param points_hull: Ordered hull points - * (result of #BLI_convexhull_2d mapped to a contiguous array). - * - * \note we could return the index of the best edge too if its needed. - */ float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n) { unsigned int i, i_prev; @@ -291,11 +263,6 @@ float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned in return (area_best != FLT_MAX) ? atan2f(dvec_best[0], dvec_best[1]) : 0.0f; } -/** - * Wrap #BLI_convexhull_aabb_fit_hull_2d and do the convex hull calculation. - * - * \param points: arbitrary 2d points. - */ float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n) { int *index_map; diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index 6c397fae836..d8e59b6f6ee 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -272,10 +272,6 @@ void BLI_edgehash_print(EdgeHash *eh) } } -/** - * Insert edge (\a v0, \a v1) into hash with given value, does - * not check for duplicates. - */ void BLI_edgehash_insert(EdgeHash *eh, uint v0, uint v1, void *value) { edgehash_ensure_can_insert(eh); @@ -283,9 +279,6 @@ void BLI_edgehash_insert(EdgeHash *eh, uint v0, uint v1, void *value) edgehash_insert(eh, edge, value); } -/** - * Assign a new value to a key that may already be in edgehash. - */ bool BLI_edgehash_reinsert(EdgeHash *eh, uint v0, uint v1, void *value) { Edge edge = init_edge(v0, v1); @@ -307,51 +300,24 @@ bool BLI_edgehash_reinsert(EdgeHash *eh, uint v0, uint v1, void *value) } } -/** - * A version of #BLI_edgehash_lookup which accepts a fallback argument. - */ void *BLI_edgehash_lookup_default(const EdgeHash *eh, uint v0, uint v1, void *default_value) { EdgeHashEntry *entry = edgehash_lookup_entry(eh, v0, v1); return entry ? entry->value : default_value; } -/** - * Return value for given edge (\a v0, \a v1), or NULL if - * if key does not exist in hash. (If need exists - * to differentiate between key-value being NULL and - * lack of key then see #BLI_edgehash_lookup_p(). - */ void *BLI_edgehash_lookup(const EdgeHash *eh, uint v0, uint v1) { EdgeHashEntry *entry = edgehash_lookup_entry(eh, v0, v1); return entry ? entry->value : NULL; } -/** - * Return pointer to value for given edge (\a v0, \a v1), - * or NULL if key does not exist in hash. - */ void **BLI_edgehash_lookup_p(EdgeHash *eh, uint v0, uint v1) { EdgeHashEntry *entry = edgehash_lookup_entry(eh, v0, v1); return entry ? &entry->value : NULL; } -/** - * Ensure \a (v0, v1) is exists in \a eh. - * - * This handles the common situation where the caller needs ensure a key is added to \a eh, - * constructing a new value in the case the key isn't found. - * Otherwise use the existing value. - * - * Such situations typically incur multiple lookups, however this function - * avoids them by ensuring the key is added, - * returning a pointer to the value so it can be used or initialized by the caller. - * - * \returns true when the value didn't need to be added. - * (when false, the caller _must_ initialize the value). - */ bool BLI_edgehash_ensure_p(EdgeHash *eh, uint v0, uint v1, void ***r_value) { Edge edge = init_edge(v0, v1); @@ -373,13 +339,6 @@ bool BLI_edgehash_ensure_p(EdgeHash *eh, uint v0, uint v1, void ***r_value) } } -/** - * Remove \a key (v0, v1) from \a eh, or return false if the key wasn't found. - * - * \param v0, v1: The key to remove. - * \param free_value: Optional callback to free the value. - * \return true if \a key was removed from \a eh. - */ bool BLI_edgehash_remove(EdgeHash *eh, uint v0, uint v1, EdgeHashFreeFP free_value) { uint old_length = eh->length; @@ -390,16 +349,11 @@ bool BLI_edgehash_remove(EdgeHash *eh, uint v0, uint v1, EdgeHashFreeFP free_val return old_length > eh->length; } -/* same as above but return the value, - * no free value argument since it will be returned */ -/** - * Remove \a key (v0, v1) from \a eh, returning the value or NULL if the key wasn't found. - * - * \param v0, v1: The key to remove. - * \return the value of \a key int \a eh or NULL. - */ void *BLI_edgehash_popkey(EdgeHash *eh, uint v0, uint v1) { + /* Same as #BLI_edgehash_remove but return the value, + * no free value argument since it will be returned */ + Edge edge = init_edge(v0, v1); ITER_SLOTS (eh, edge, slot, index) { @@ -420,25 +374,16 @@ void *BLI_edgehash_popkey(EdgeHash *eh, uint v0, uint v1) } } -/** - * Return boolean true/false if edge (v0,v1) in hash. - */ bool BLI_edgehash_haskey(const EdgeHash *eh, uint v0, uint v1) { return edgehash_lookup_entry(eh, v0, v1) != NULL; } -/** - * Return number of keys in hash. - */ int BLI_edgehash_len(const EdgeHash *eh) { return (int)eh->length; } -/** - * Remove all edges from hash. - */ void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP free_value, const uint UNUSED(reserve)) { /* TODO: handle reserve */ @@ -449,9 +394,6 @@ void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP free_value, const uint U CLEAR_MAP(eh); } -/** - * Wraps #BLI_edgehash_clear_ex with zero entries reserved. - */ void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP free_value) { BLI_edgehash_clear_ex(eh, free_value, 0); @@ -463,11 +405,6 @@ void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP free_value) /** \name Edge Hash Iterator API * \{ */ -/** - * Create a new EdgeHashIterator. The hash table must not be mutated - * while the iterator is in use, and the iterator will step exactly - * BLI_edgehash_len(eh) times before becoming done. - */ EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) { EdgeHashIterator *ehi = MEM_mallocN(sizeof(EdgeHashIterator), __func__); @@ -475,14 +412,6 @@ EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) return ehi; } -/** - * Init an already allocated EdgeHashIterator. The hash table must not - * be mutated while the iterator is in use, and the iterator will - * step exactly BLI_edgehash_len(eh) times before becoming done. - * - * \param ehi: The EdgeHashIterator to initialize. - * \param eh: The EdgeHash to iterate over. - */ void BLI_edgehashIterator_init(EdgeHashIterator *ehi, EdgeHash *eh) { ehi->entries = eh->entries; @@ -490,9 +419,6 @@ void BLI_edgehashIterator_init(EdgeHashIterator *ehi, EdgeHash *eh) ehi->index = 0; } -/** - * Free an EdgeHashIterator. - */ void BLI_edgehashIterator_free(EdgeHashIterator *ehi) { MEM_freeN(ehi); @@ -569,12 +495,6 @@ BLI_INLINE void edgeset_insert_at_slot(EdgeSet *es, uint slot, Edge edge) es->length++; } -/** - * A version of BLI_edgeset_insert which checks first if the key is in the set. - * \returns true if a new key has been added. - * - * \note EdgeHash has no equivalent to this because typically the value would be different. - */ bool BLI_edgeset_add(EdgeSet *es, uint v0, uint v1) { edgeset_ensure_can_insert(es); @@ -591,10 +511,6 @@ bool BLI_edgeset_add(EdgeSet *es, uint v0, uint v1) } } -/** - * Adds the key to the set (no checks for unique keys!). - * Matching #BLI_edgehash_insert - */ void BLI_edgeset_insert(EdgeSet *es, uint v0, uint v1) { edgeset_ensure_can_insert(es); diff --git a/source/blender/blenlib/intern/expr_pylike_eval.c b/source/blender/blenlib/intern/expr_pylike_eval.c index 1acb8299aa2..c6be8836229 100644 --- a/source/blender/blenlib/intern/expr_pylike_eval.c +++ b/source/blender/blenlib/intern/expr_pylike_eval.c @@ -124,7 +124,6 @@ struct ExprPyLike_Parsed { /** \name Public API * \{ */ -/** Free the parsed data; NULL argument is ok. */ void BLI_expr_pylike_free(ExprPyLike_Parsed *expr) { if (expr != NULL) { @@ -132,19 +131,16 @@ void BLI_expr_pylike_free(ExprPyLike_Parsed *expr) } } -/** Check if the parsing result is valid for evaluation. */ bool BLI_expr_pylike_is_valid(ExprPyLike_Parsed *expr) { return expr != NULL && expr->ops_count > 0; } -/** Check if the parsed expression always evaluates to the same value. */ bool BLI_expr_pylike_is_constant(ExprPyLike_Parsed *expr) { return expr != NULL && expr->ops_count == 1 && expr->ops[0].opcode == OPCODE_CONST; } -/** Check if the parsed expression uses the parameter with the given index. */ bool BLI_expr_pylike_is_using_param(ExprPyLike_Parsed *expr, int index) { int i; @@ -168,10 +164,6 @@ bool BLI_expr_pylike_is_using_param(ExprPyLike_Parsed *expr, int index) /** \name Stack Machine Evaluation * \{ */ -/** - * Evaluate the expression with the given parameters. - * The order and number of parameters must match the names given to parse. - */ eExprPyLike_EvalStatus BLI_expr_pylike_eval(ExprPyLike_Parsed *expr, const double *param_values, int param_values_len, @@ -1073,12 +1065,6 @@ static bool parse_expr(ExprParseState *state) /** \name Main Parsing Function * \{ */ -/** - * Compile the expression and return the result. - * - * Parse the expression for evaluation later. - * Returns non-NULL even on failure; use is_valid to check. - */ ExprPyLike_Parsed *BLI_expr_pylike_parse(const char *expression, const char **param_names, int param_names_len) diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index c52feb097d2..838644054af 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -180,13 +180,6 @@ bool BLI_file_magic_is_zstd(const char header[4]) return false; } -/** - * Returns true if the file with the specified name can be written. - * This implementation uses access(2), which makes the check according - * to the real UID and GID of the process, not its effective UID and GID. - * This shouldn't matter for Blender, which is not going to run privileged - * anyway. - */ bool BLI_file_is_writable(const char *filename) { bool writable; @@ -212,10 +205,6 @@ bool BLI_file_is_writable(const char *filename) return writable; } -/** - * Creates the file with nothing in it, or updates its last-modified date if it already exists. - * Returns true if successful (like the unix touch command). - */ bool BLI_file_touch(const char *file) { FILE *f = BLI_fopen(file, "r+b"); @@ -954,12 +943,6 @@ int BLI_access(const char *filename, int mode) return access(filename, mode); } -/** - * Deletes the specified file or directory (depending on dir), optionally - * doing recursive delete of directory contents. - * - * \return zero on success (matching 'remove' behavior). - */ int BLI_delete(const char *file, bool dir, bool recursive) { BLI_assert(!BLI_path_is_rel(file)); @@ -973,12 +956,6 @@ int BLI_delete(const char *file, bool dir, bool recursive) return remove(file); } -/** - * Soft deletes the specified file or directory (depending on dir) by moving the files to the - * recycling bin, optionally doing recursive delete of directory contents. - * - * \return zero on success (matching 'remove' behavior). - */ int BLI_delete_soft(const char *file, const char **error_message) { BLI_assert(!BLI_path_is_rel(file)); @@ -1251,7 +1228,6 @@ int BLI_create_symlink(const char *file, const char *to) } # endif -/** \return true on success (i.e. given path now exists on FS), false otherwise. */ bool BLI_dir_create_recursive(const char *dirname) { char *lslash; @@ -1301,9 +1277,6 @@ bool BLI_dir_create_recursive(const char *dirname) return ret; } -/** - * \return zero on success (matching 'rename' behavior). - */ int BLI_rename(const char *from, const char *to) { if (!BLI_exists(from)) { diff --git a/source/blender/blenlib/intern/gsqueue.c b/source/blender/blenlib/intern/gsqueue.c index ae34074e804..1bd99497432 100644 --- a/source/blender/blenlib/intern/gsqueue.c +++ b/source/blender/blenlib/intern/gsqueue.c @@ -101,9 +101,6 @@ static void queue_free_chunk(struct QueueChunk *data) } } -/** - * Free the queue's data and the queue itself - */ void BLI_gsqueue_free(GSQueue *queue) { queue_free_chunk(queue->chunk_first); @@ -111,14 +108,6 @@ void BLI_gsqueue_free(GSQueue *queue) MEM_freeN(queue); } -/** - * Copies the source value onto the end of the queue - * - * \note This copies #GSQueue.elem_size bytes from \a item, - * (the pointer itself is not stored). - * - * \param item: source data to be copied to the queue. - */ void BLI_gsqueue_push(GSQueue *queue, const void *item) { queue->chunk_last_index++; @@ -153,12 +142,6 @@ void BLI_gsqueue_push(GSQueue *queue, const void *item) memcpy(queue_get_last_elem(queue), item, queue->elem_size); } -/** - * Retrieves and removes the first element from the queue. - * The value is copies to \a r_item, which must be at least \a elem_size bytes. - * - * Does not reduce amount of allocated memory. - */ void BLI_gsqueue_pop(GSQueue *queue, void *r_item) { BLI_assert(BLI_gsqueue_is_empty(queue) == false); @@ -187,9 +170,6 @@ size_t BLI_gsqueue_len(const GSQueue *queue) return queue->totelem; } -/** - * Returns true if the queue is empty, false otherwise - */ bool BLI_gsqueue_is_empty(const GSQueue *queue) { return (queue->chunk_first == NULL); diff --git a/source/blender/blenlib/intern/hash_md5.c b/source/blender/blenlib/intern/hash_md5.c index 3db1b7df0fa..6a0ca8bb33f 100644 --- a/source/blender/blenlib/intern/hash_md5.c +++ b/source/blender/blenlib/intern/hash_md5.c @@ -284,11 +284,6 @@ static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf) /* Top level public functions. */ -/** - * Compute MD5 message digest for bytes read from 'stream'. - * The resulting message digest number will be written into the 16 bytes beginning at 'resblock'. - * \return Non-zero if an error occurred. - */ int BLI_hash_md5_stream(FILE *stream, void *resblock) { #define BLOCKSIZE 4096 /* Important: must be a multiple of 64. */ @@ -362,11 +357,6 @@ int BLI_hash_md5_stream(FILE *stream, void *resblock) return 0; } -/** - * Compute MD5 message digest for 'len' bytes beginning at 'buffer'. - * The result is always in little endian byte order, - * so that a byte-wise output yields to the wanted ASCII representation of the message digest. - */ void *BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock) { struct md5_ctx ctx; diff --git a/source/blender/blenlib/intern/hash_mm2a.c b/source/blender/blenlib/intern/hash_mm2a.c index 0899491cd0d..a98ae083fc8 100644 --- a/source/blender/blenlib/intern/hash_mm2a.c +++ b/source/blender/blenlib/intern/hash_mm2a.c @@ -110,7 +110,6 @@ uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2) return mm2->hash; } -/* Non-incremental version, quicker for small keys. */ uint32_t BLI_hash_mm2(const unsigned char *data, size_t len, uint32_t seed) { /* Initialize the hash to a 'random' value */ diff --git a/source/blender/blenlib/intern/index_mask.cc b/source/blender/blenlib/intern/index_mask.cc index d726dff6d16..a73e6caf313 100644 --- a/source/blender/blenlib/intern/index_mask.cc +++ b/source/blender/blenlib/intern/index_mask.cc @@ -23,21 +23,6 @@ IndexMask IndexMask::slice(IndexRange slice) const return IndexMask(indices_.slice(slice)); } -/** - * Create a sub-mask that is also shifted to the beginning. The shifting to the beginning allows - * code to work with smaller indices, which is more memory efficient. - * - * \return New index mask with the size of #slice. It is either empty or starts with 0. It might - * reference indices that have been appended to #r_new_indices. - * - * Example: - * this: [2, 3, 5, 7, 8, 9, 10] - * slice: ^--------^ - * output: [0, 2, 4, 5] - * - * All the indices in the sub-mask are shifted by 3 towards zero, so that the first index in the - * output is zero. - */ IndexMask IndexMask::slice_and_offset(const IndexRange slice, Vector<int64_t> &r_new_indices) const { const int slice_size = slice.size(); diff --git a/source/blender/blenlib/intern/lasso_2d.c b/source/blender/blenlib/intern/lasso_2d.c index a3b111cf0f2..ee10a233d39 100644 --- a/source/blender/blenlib/intern/lasso_2d.c +++ b/source/blender/blenlib/intern/lasso_2d.c @@ -65,7 +65,6 @@ bool BLI_lasso_is_point_inside(const int mcoords[][2], return isect_point_poly_v2_int(pt, mcoords, mcoords_len, true); } -/* edge version for lasso select. we assume boundbox check was done */ bool BLI_lasso_is_edge_inside(const int mcoords[][2], const unsigned int mcoords_len, int x0, diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 443bef42cc2..a166c846ea7 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -36,11 +36,6 @@ #include "BLI_strict_flags.h" -/* implementation */ - -/** - * moves the entire contents of \a src onto the end of \a dst. - */ void BLI_movelisttolist(ListBase *dst, ListBase *src) { if (src->first == NULL) { @@ -59,9 +54,6 @@ void BLI_movelisttolist(ListBase *dst, ListBase *src) src->first = src->last = NULL; } -/** - * moves the entire contents of \a src at the beginning of \a dst. - */ void BLI_movelisttolist_reverse(ListBase *dst, ListBase *src) { if (src->first == NULL) { @@ -81,9 +73,6 @@ void BLI_movelisttolist_reverse(ListBase *dst, ListBase *src) src->first = src->last = NULL; } -/** - * Prepends \a vlink (assumed to begin with a Link) onto listbase. - */ void BLI_addhead(ListBase *listbase, void *vlink) { Link *link = vlink; @@ -104,9 +93,6 @@ void BLI_addhead(ListBase *listbase, void *vlink) listbase->first = link; } -/** - * Appends \a vlink (assumed to begin with a Link) onto listbase. - */ void BLI_addtail(ListBase *listbase, void *vlink) { Link *link = vlink; @@ -127,9 +113,6 @@ void BLI_addtail(ListBase *listbase, void *vlink) listbase->last = link; } -/** - * Removes \a vlink from \a listbase. Assumes it is linked into there! - */ void BLI_remlink(ListBase *listbase, void *vlink) { Link *link = vlink; @@ -153,9 +136,6 @@ void BLI_remlink(ListBase *listbase, void *vlink) } } -/** - * Checks that \a vlink is linked into listbase, removing it from there if so. - */ bool BLI_remlink_safe(ListBase *listbase, void *vlink) { if (BLI_findindex(listbase, vlink) != -1) { @@ -166,9 +146,6 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink) return false; } -/** - * Swaps \a vlinka and \a vlinkb in the list. Assumes they are both already in the list! - */ void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) { Link *linka = vlinka; @@ -222,10 +199,6 @@ void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) } } -/** - * Swaps \a vlinka and \a vlinkb from their respective lists. - * Assumes they are both already in their \a listbasea! - */ void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb) { Link *linka = vlinka; @@ -251,9 +224,6 @@ void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vli BLI_remlink(listbasea, &linkc); } -/** - * Removes the head from \a listbase and returns it. - */ void *BLI_pophead(ListBase *listbase) { Link *link; @@ -263,9 +233,6 @@ void *BLI_pophead(ListBase *listbase) return link; } -/** - * Removes the tail from \a listbase and returns it. - */ void *BLI_poptail(ListBase *listbase) { Link *link; @@ -275,9 +242,6 @@ void *BLI_poptail(ListBase *listbase) return link; } -/** - * Removes \a vlink from listbase and disposes of it. Assumes it is linked into there! - */ void BLI_freelinkN(ListBase *listbase, void *vlink) { Link *link = vlink; @@ -320,11 +284,6 @@ static void listbase_double_from_single(Link *iter, ListBase *listbase) #undef SORT_IMPL_LINKTYPE -/** - * Sorts the elements of listbase into the order defined by cmp - * (which should return 1 if its first arg should come after its second arg). - * This uses insertion sort, so NOT ok for large list. - */ void BLI_listbase_sort(ListBase *listbase, int (*cmp)(const void *, const void *)) { if (listbase->first != listbase->last) { @@ -345,10 +304,6 @@ void BLI_listbase_sort_r(ListBase *listbase, } } -/** - * Inserts \a vnewlink immediately following \a vprevlink in \a listbase. - * Or, if \a vprevlink is NULL, puts \a vnewlink at the front of the list. - */ void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) { Link *prevlink = vprevlink; @@ -388,10 +343,6 @@ void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) } } -/** - * Inserts \a vnewlink immediately preceding \a vnextlink in listbase. - * Or, if \a vnextlink is NULL, puts \a vnewlink at the end of the list. - */ void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) { Link *nextlink = vnextlink; @@ -431,13 +382,6 @@ void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) } } -/** - * Insert a link in place of another, without changing its position in the list. - * - * Puts `vnewlink` in the position of `vreplacelink`, removing `vreplacelink`. - * - `vreplacelink` *must* be in the list. - * - `vnewlink` *must not* be in the list. - */ void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink) { Link *l_old = vreplacelink; @@ -464,14 +408,6 @@ void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlin } } -/** - * Reinsert \a vlink relative to its current position but offset by \a step. Doesn't move - * item if new position would exceed list (could optionally move to head/tail). - * - * \param step: Absolute value defines step size, sign defines direction. E.g pass -1 - * to move \a vlink before previous, or 1 to move behind next. - * \return If position of \a vlink has changed. - */ bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) { Link *link = vlink; @@ -503,11 +439,6 @@ bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) return true; } -/** - * Move the link at the index \a from to the position at index \a to. - * - * \return If the move was successful. - */ bool BLI_listbase_move_index(ListBase *listbase, int from, int to) { if (from == to) { @@ -524,9 +455,6 @@ bool BLI_listbase_move_index(ListBase *listbase, int from, int to) return BLI_listbase_link_move(listbase, link, to - from); } -/** - * Removes and disposes of the entire contents of listbase using direct free(3). - */ void BLI_freelist(ListBase *listbase) { Link *link, *next; @@ -541,9 +469,6 @@ void BLI_freelist(ListBase *listbase) BLI_listbase_clear(listbase); } -/** - * Removes and disposes of the entire contents of \a listbase using guardedalloc. - */ void BLI_freelistN(ListBase *listbase) { Link *link, *next; @@ -558,11 +483,6 @@ void BLI_freelistN(ListBase *listbase) BLI_listbase_clear(listbase); } -/** - * Returns the number of elements in \a listbase, up until (and including count_max) - * - * \note Use to avoid redundant looping. - */ int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max) { Link *link; @@ -575,9 +495,6 @@ int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max) return count; } -/** - * Returns the number of elements in \a listbase. - */ int BLI_listbase_count(const ListBase *listbase) { Link *link; @@ -590,9 +507,6 @@ int BLI_listbase_count(const ListBase *listbase) return count; } -/** - * Returns the nth element of \a listbase, numbering from 0. - */ void *BLI_findlink(const ListBase *listbase, int number) { Link *link = NULL; @@ -608,9 +522,6 @@ void *BLI_findlink(const ListBase *listbase, int number) return link; } -/** - * Returns the nth-last element of \a listbase, numbering from 0. - */ void *BLI_rfindlink(const ListBase *listbase, int number) { Link *link = NULL; @@ -626,9 +537,6 @@ void *BLI_rfindlink(const ListBase *listbase, int number) return link; } -/** - * Returns the position of \a vlink within \a listbase, numbering from 0, or -1 if not found. - */ int BLI_findindex(const ListBase *listbase, const void *vlink) { Link *link = NULL; @@ -651,10 +559,6 @@ int BLI_findindex(const ListBase *listbase, const void *vlink) return -1; } -/** - * Finds the first element of \a listbase which contains the null-terminated - * string \a id at the specified offset, returning NULL if not found. - */ void *BLI_findstring(const ListBase *listbase, const char *id, const int offset) { Link *link = NULL; @@ -674,13 +578,10 @@ void *BLI_findstring(const ListBase *listbase, const char *id, const int offset) return NULL; } -/* same as above but find reverse */ -/** - * Finds the last element of \a listbase which contains the - * null-terminated string \a id at the specified offset, returning NULL if not found. - */ void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset) { + /* Same as #BLI_findstring but find reverse. */ + Link *link = NULL; const char *id_iter; @@ -695,10 +596,6 @@ void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset return NULL; } -/** - * Finds the first element of \a listbase which contains a pointer to the - * null-terminated string \a id at the specified offset, returning NULL if not found. - */ void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int offset) { Link *link = NULL; @@ -715,13 +612,10 @@ void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int off return NULL; } -/* same as above but find reverse */ -/** - * Finds the last element of \a listbase which contains a pointer to the - * null-terminated string \a id at the specified offset, returning NULL if not found. - */ void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int offset) { + /* Same as #BLI_findstring_ptr but find reverse. */ + Link *link = NULL; const char *id_iter; @@ -737,10 +631,6 @@ void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int of return NULL; } -/** - * Finds the first element of listbase which contains the specified pointer value - * at the specified offset, returning NULL if not found. - */ void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset) { Link *link = NULL; @@ -757,13 +647,10 @@ void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset) return NULL; } -/* same as above but find reverse */ -/** - * Finds the last element of listbase which contains the specified pointer value - * at the specified offset, returning NULL if not found. - */ void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset) { + /* Same as #BLI_findptr but find reverse. */ + Link *link = NULL; const void *ptr_iter; @@ -779,10 +666,6 @@ void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset) return NULL; } -/** - * Finds the first element of listbase which contains the specified bytes - * at the specified offset, returning NULL if not found. - */ void *BLI_listbase_bytes_find(const ListBase *listbase, const void *bytes, const size_t bytes_size, @@ -801,16 +684,13 @@ void *BLI_listbase_bytes_find(const ListBase *listbase, return NULL; } -/* same as above but find reverse */ -/** - * Finds the last element of listbase which contains the specified bytes - * at the specified offset, returning NULL if not found. - */ void *BLI_listbase_bytes_rfind(const ListBase *listbase, const void *bytes, const size_t bytes_size, const int offset) { + /* Same as #BLI_listbase_bytes_find but find reverse. */ + Link *link = NULL; const void *ptr_iter; @@ -825,13 +705,6 @@ void *BLI_listbase_bytes_rfind(const ListBase *listbase, return NULL; } -/** - * Find the first item in the list that matches the given string, or the given index as fallback. - * - * \note The string is only used is non-NULL and non-empty. - * - * \return The found item, or NULL. - */ void *BLI_listbase_string_or_index_find(const ListBase *listbase, const char *string, const size_t string_offset, @@ -856,10 +729,6 @@ void *BLI_listbase_string_or_index_find(const ListBase *listbase, return link_at_index; } -/** - * Returns the 0-based index of the first element of listbase which contains the specified - * null-terminated string at the specified offset, or -1 if not found. - */ int BLI_findstringindex(const ListBase *listbase, const char *id, const int offset) { Link *link = NULL; @@ -880,9 +749,6 @@ int BLI_findstringindex(const ListBase *listbase, const char *id, const int offs return -1; } -/** - * Sets dst to a duplicate of the entire contents of src. dst may be the same as src. - */ void BLI_duplicatelist(ListBase *dst, const ListBase *src) { struct Link *dst_link, *src_link; @@ -918,9 +784,6 @@ void BLI_listbase_reverse(ListBase *lb) lb->last = curr; } -/** - * \param vlink: Link to make first. - */ void BLI_listbase_rotate_first(ListBase *lb, void *vlink) { /* make circular */ @@ -934,9 +797,6 @@ void BLI_listbase_rotate_first(ListBase *lb, void *vlink) ((Link *)lb->last)->next = NULL; } -/** - * \param vlink: Link to make last. - */ void BLI_listbase_rotate_last(ListBase *lb, void *vlink) { /* make circular */ @@ -950,7 +810,6 @@ void BLI_listbase_rotate_last(ListBase *lb, void *vlink) ((Link *)lb->last)->next = NULL; } -/* create a generic list node containing link to provided data */ LinkData *BLI_genericNodeN(void *data) { LinkData *ld; diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c index 1137c4114a5..be70acf622a 100644 --- a/source/blender/blenlib/intern/math_base.c +++ b/source/blender/blenlib/intern/math_base.c @@ -42,10 +42,10 @@ int pow_i(int base, int exp) return result; } -/* from python 3.1 floatobject.c - * ndigits must be between 0 and 21 */ double double_round(double x, int ndigits) { + /* From Python 3.1 `floatobject.c`. */ + double pow1, pow2, y, z; if (ndigits >= 0) { pow1 = pow(10.0, (double)ndigits); @@ -79,15 +79,6 @@ double double_round(double x, int ndigits) return z; } -/** - * Floor to the nearest power of 10, e.g.: - * - 15.0 -> 10.0 - * - 0.015 -> 0.01 - * - 1.0 -> 1.0 - * - * \param f: Value to floor, must be over 0.0. - * \note If we wanted to support signed values we could if this becomes necessary. - */ float floor_power_of_10(float f) { BLI_assert(!(f < 0.0f)); @@ -97,15 +88,6 @@ float floor_power_of_10(float f) return 0.0f; } -/** - * Ceiling to the nearest power of 10, e.g.: - * - 15.0 -> 100.0 - * - 0.015 -> 0.1 - * - 1.0 -> 1.0 - * - * \param f: Value to ceiling, must be over 0.0. - * \note If we wanted to support signed values we could if this becomes necessary. - */ float ceil_power_of_10(float f) { BLI_assert(!(f < 0.0f)); diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index f609d5f8e8b..53cf2d61963 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -45,7 +45,6 @@ extern "C" { # define UNLIKELY(x) (x) #endif -/* powf is really slow for raising to integer powers. */ MINLINE float pow2f(float x) { return x * x; @@ -192,21 +191,18 @@ MINLINE double ratiod(double min, double max, double pos) return range == 0 ? 0 : ((pos - min) / range); } -/* Map a normalized value, i.e. from interval [0, 1] to interval [a, b]. */ MINLINE float scalenorm(float a, float b, float x) { BLI_assert(x <= 1 && x >= 0); return (x * (b - a)) + a; } -/* Map a normalized value, i.e. from interval [0, 1] to interval [a, b]. */ MINLINE double scalenormd(double a, double b, double x) { BLI_assert(x <= 1 && x >= 0); return (x * (b - a)) + a; } -/* Used for zoom values. */ MINLINE float power_of_2(float val) { return (float)pow(2.0, ceil(log((double)val) / M_LN2)); @@ -363,16 +359,11 @@ MINLINE signed char round_db_to_char_clamp(double a){ #undef _round_clamp_fl_impl #undef _round_clamp_db_impl -/** - * Round to closest even number, halfway cases are rounded away from zero. - */ MINLINE float round_to_even(float f) { return roundf(f * 0.5f) * 2.0f; } -/* integer division that rounds 0.5 up, particularly useful for color blending - * with integers, to avoid gradual darkening when rounding down */ MINLINE int divide_round_i(int a, int b) { return (2 * a + b) / (2 * b); @@ -397,9 +388,6 @@ MINLINE uint divide_ceil_u(uint a, uint b) return (a + b - 1) / b; } -/** - * modulo that handles negative numbers, works the same as Python's. - */ MINLINE int mod_i(int i, int n) { return (i % n + n) % n; @@ -629,27 +617,11 @@ MINLINE size_t clamp_z(size_t value, size_t min, size_t max) return min_zz(max_zz(value, min), max); } -/** - * Almost-equal for IEEE floats, using absolute difference method. - * - * \param max_diff: the maximum absolute difference. - */ MINLINE int compare_ff(float a, float b, const float max_diff) { return fabsf(a - b) <= max_diff; } -/** - * Almost-equal for IEEE floats, using their integer representation - * (mixing ULP and absolute difference methods). - * - * \param max_diff: is the maximum absolute difference (allows to take care of the near-zero area, - * where relative difference methods cannot really work). - * \param max_ulps: is the 'maximum number of floats + 1' - * allowed between \a a and \a b to consider them equal. - * - * \see https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ - */ MINLINE int compare_ff_relative(float a, float b, const float max_diff, const int max_ulps) { union { @@ -728,19 +700,11 @@ MINLINE int signum_i(float a) } } -/** - * Returns number of (base ten) *significant* digits of integer part of given float - * (negative in case of decimal-only floats, 0.01 returns -1 e.g.). - */ MINLINE int integer_digits_f(const float f) { return (f == 0.0f) ? 0 : (int)floor(log10(fabs(f))) + 1; } -/** - * Returns number of (base ten) *significant* digits of integer part of given double - * (negative in case of decimal-only floats, 0.01 returns -1 e.g.). - */ MINLINE int integer_digits_d(const double d) { return (d == 0.0) ? 0 : (int)floor(log10(fabs(d))) + 1; diff --git a/source/blender/blenlib/intern/math_boolean.cc b/source/blender/blenlib/intern/math_boolean.cc index 6d4806a3fbc..c16755868aa 100644 --- a/source/blender/blenlib/intern/math_boolean.cc +++ b/source/blender/blenlib/intern/math_boolean.cc @@ -33,10 +33,6 @@ namespace blender { #ifdef WITH_GMP -/** - * Return +1 if a, b, c are in CCW order around a circle in the plane. - * Return -1 if they are in CW order, and 0 if they are in line. - */ int orient2d(const mpq2 &a, const mpq2 &b, const mpq2 &c) { mpq_class detleft = (a[0] - c[0]) * (b[1] - c[1]); @@ -45,11 +41,6 @@ int orient2d(const mpq2 &a, const mpq2 &b, const mpq2 &c) return sgn(det); } -/** - Return +1 if d is in the oriented circle through a, b, and c. - * The oriented circle goes CCW through a, b, and c. - * Return -1 if d is outside, and 0 if it is on the circle. - */ int incircle(const mpq2 &a, const mpq2 &b, const mpq2 &c, const mpq2 &d) { mpq_class adx = a[0] - d[0]; @@ -76,12 +67,6 @@ int incircle(const mpq2 &a, const mpq2 &b, const mpq2 &c, const mpq2 &d) return sgn(det); } -/** - * Return +1 if d is below the plane containing a, b, c (which appear - * CCW when viewed from above the plane). - * Return -1 if d is above the plane. - * Return 0 if it is on the plane. - */ int orient3d(const mpq3 &a, const mpq3 &b, const mpq3 &c, const mpq3 &d) { mpq_class adx = a[0] - d[0]; diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 14eb78648e0..5e52873649e 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -64,13 +64,11 @@ void hsl_to_rgb(float h, float s, float l, float *r_r, float *r_g, float *r_b) *r_b = (nb - 0.5f) * chroma + l; } -/* convenience function for now */ void hsv_to_rgb_v(const float hsv[3], float r_rgb[3]) { hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]); } -/* convenience function for now */ void hsl_to_rgb_v(const float hsl[3], float r_rgb[3]) { hsl_to_rgb(hsl[0], hsl[1], hsl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]); @@ -124,9 +122,6 @@ void yuv_to_rgb(float y, float u, float v, float *r_r, float *r_g, float *r_b, i *r_b = b; } -/* The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f - * - * Output YCC have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */ void rgb_to_ycc(float r, float g, float b, float *r_y, float *r_cb, float *r_cr, int colorspace) { float sr, sg, sb; @@ -162,12 +157,14 @@ void rgb_to_ycc(float r, float g, float b, float *r_y, float *r_cb, float *r_cr, *r_cr = cr; } -/* YCC input have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */ -/* RGB outputs are in the range 0 - 1.0f */ - -/* FIXME comment above must be wrong because BLI_YCC_ITU_BT601 y 16.0 cr 16.0 -> r -0.7009 */ void ycc_to_rgb(float y, float cb, float cr, float *r_r, float *r_g, float *r_b, int colorspace) { + /* FIXME the following comment must be wrong because: + * BLI_YCC_ITU_BT601 y 16.0 cr 16.0 -> r -0.7009. */ + + /* YCC input have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 + * RGB outputs are in the range 0 - 1.0f. */ + float r = 128.0f, g = 128.0f, b = 128.0f; switch (colorspace) { @@ -250,7 +247,6 @@ void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v) *r_v = r; } -/* convenience function for now */ void rgb_to_hsv_v(const float rgb[3], float r_hsv[3]) { rgb_to_hsv(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]); @@ -311,7 +307,6 @@ void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3]) rgb_to_hsl_compat(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]); } -/* convenience function for now */ void rgb_to_hsl_v(const float rgb[3], float r_hsl[3]) { rgb_to_hsl(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]); @@ -338,13 +333,11 @@ void rgb_to_hsv_compat(float r, float g, float b, float *r_h, float *r_s, float } } -/* convenience function for now */ void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3]) { rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]); } -/* clamp hsv to usable values */ void hsv_clamp_v(float hsv[3], float v_max) { if (UNLIKELY(hsv[0] < 0.0f || hsv[0] > 1.0f)) { @@ -354,12 +347,6 @@ void hsv_clamp_v(float hsv[3], float v_max) CLAMP(hsv[2], 0.0f, v_max); } -/** - * We define a 'cpack' here as a (3 byte color code) - * number that can be expressed like 0xFFAA66 or so. - * For that reason it is sensitive for endianness... with this function it works correctly. - * \see #imm_cpack - */ unsigned int hsv_to_cpack(float h, float s, float v) { unsigned int r, g, b; @@ -473,12 +460,6 @@ void minmax_rgb(short c[3]) } } -/* If the requested RGB shade contains a negative weight for - * one of the primaries, it lies outside the color gamut - * accessible from the given triple of primaries. Desaturate - * it by adding white, equal quantities of R, G, and B, enough - * to make RGB all positive. The function returns 1 if the - * components were modified, zero otherwise. */ int constrain_rgb(float *r, float *g, float *b) { /* Amount of white needed */ @@ -520,7 +501,6 @@ void lift_gamma_gain_to_asc_cdl(const float *lift, /* ************************************* other ************************************************* */ -/* Applies an hue offset to a float rgb color */ void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset) { float hsv[3]; @@ -538,7 +518,6 @@ void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset) hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2); } -/* Applies an hue offset to a byte rgb color */ void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset) { float rgb_float[3]; diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c index 24c4143e587..febe1568176 100644 --- a/source/blender/blenlib/intern/math_color_inline.c +++ b/source/blender/blenlib/intern/math_color_inline.c @@ -271,20 +271,6 @@ MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack) * * \{ */ -/** - * ITU-R BT.709 primaries - * https://en.wikipedia.org/wiki/Relative_luminance - * - * Real values are: - * `Y = 0.2126390059(R) + 0.7151686788(G) + 0.0721923154(B)` - * according to: "Derivation of Basic Television Color Equations", RP 177-1993 - * - * As this sums slightly above 1.0, the document recommends to use: - * `0.2126(R) + 0.7152(G) + 0.0722(B)`, as used here. - * - * The high precision values are used to calculate the rounded byte weights so they add up to 255: - * `54(R) + 182(G) + 19(B)` - */ MINLINE float rgb_to_grayscale(const float rgb[3]) { return (0.2126f * rgb[0]) + (0.7152f * rgb[1]) + (0.0722f * rgb[2]); @@ -317,11 +303,11 @@ MINLINE int compare_rgb_uchar(const unsigned char col_a[3], return 0; } -/* Using a triangle distribution which gives a more final uniform noise. - * See Banding in Games:A Noisy Rant(revision 5) Mikkel Gjøl, Playdead (slide 27) */ -/* Return triangle noise in [-0.5..1.5[ range */ MINLINE float dither_random_value(float s, float t) { + /* Using a triangle distribution which gives a more final uniform noise. + * See Banding in Games:A Noisy Rant(revision 5) Mikkel Gjøl, Playdead (slide 27) */ + /* Uniform noise in [0..1[ range, using common GLSL hash function. * https://stackoverflow.com/questions/12964279/whats-the-origin-of-this-glsl-rand-one-liner. */ float hash0 = sinf(s * 12.9898f + t * 78.233f) * 43758.5453f; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 8afb6b5a2be..e2bf842b8d0 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -86,11 +86,6 @@ float normal_quad_v3( return normalize_v3(n); } -/** - * Computes the normal of a planar - * polygon See Graphics Gems for - * computing newell normal. - */ float normal_poly_v3(float n[3], const float verts[][3], unsigned int nr) { cross_poly_v3(n, verts, nr); @@ -112,7 +107,6 @@ float area_squared_quad_v3(const float v1[3], return area_squared_poly_v3(verts, 4); } -/* Triangles */ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3]) { float n[3]; @@ -162,12 +156,6 @@ float area_squared_poly_v3(const float verts[][3], unsigned int nr) return len_squared_v3(n); } -/** - * Scalar cross product of a 2d polygon. - * - * - equivalent to `area * 2` - * - useful for checking polygon winding (a positive value is clockwise). - */ float cross_poly_v2(const float verts[][2], unsigned int nr) { unsigned int a; @@ -236,28 +224,18 @@ float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float /********************************* Planes **********************************/ -/** - * Calculate a plane from a point and a direction, - * \note \a point_no isn't required to be normalized. - */ void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3]) { copy_v3_v3(r_plane, plane_no); r_plane[3] = -dot_v3v3(r_plane, plane_co); } -/** - * Get a point and a direction from a plane. - */ void plane_to_point_vector_v3(const float plane[4], float r_plane_co[3], float r_plane_no[3]) { mul_v3_v3fl(r_plane_co, plane, (-plane[3] / len_squared_v3(plane))); copy_v3_v3(r_plane_no, plane); } -/** - * version of #plane_to_point_vector_v3 that gets a unit length vector. - */ void plane_to_point_vector_v3_normalized(const float plane[4], float r_plane_co[3], float r_plane_no[3]) @@ -268,9 +246,6 @@ void plane_to_point_vector_v3_normalized(const float plane[4], /********************************* Volume **********************************/ -/** - * The volume from a tetrahedron, points can be in any order - */ float volume_tetrahedron_v3(const float v1[3], const float v2[3], const float v3[3], @@ -283,9 +258,6 @@ float volume_tetrahedron_v3(const float v1[3], return fabsf(determinant_m3_array(m)) / 6.0f; } -/** - * The volume from a tetrahedron, normal pointing inside gives negative volume - */ float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3], @@ -298,12 +270,6 @@ float volume_tetrahedron_signed_v3(const float v1[3], return determinant_m3_array(m) / 6.0f; } -/** - * The volume from a triangle that is made into a tetrahedron. - * This uses a simplified formula where the tip of the tetrahedron is in the world origin. - * Using this method, the total volume of a closed triangle mesh can be calculated. - * Note that you need to divide the result by 6 to get the actual volume. - */ float volume_tri_tetrahedron_signed_v3_6x(const float v1[3], const float v2[3], const float v3[3]) { float v_cross[3]; @@ -319,8 +285,6 @@ float volume_tri_tetrahedron_signed_v3(const float v1[3], const float v2[3], con /********************************* Distance **********************************/ -/* distance p to line v1-v2 - * using Hesse formula, NO LINE PIECE! */ float dist_squared_to_line_v2(const float p[2], const float l1[2], const float l2[2]) { float closest[2]; @@ -334,7 +298,6 @@ float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]) return sqrtf(dist_squared_to_line_v2(p, l1, l2)); } -/* distance p to line-piece v1-v2 */ float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]) { float closest[2]; @@ -349,7 +312,6 @@ float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l return sqrtf(dist_squared_to_line_segment_v2(p, l1, l2)); } -/* point closest to v1 on line v2-v3 in 2D */ void closest_to_line_segment_v2(float r_close[2], const float p[2], const float l1[2], @@ -371,7 +333,6 @@ void closest_to_line_segment_v2(float r_close[2], } } -/* point closest to v1 on line v2-v3 in 3D */ void closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], @@ -393,15 +354,6 @@ void closest_to_line_segment_v3(float r_close[3], } } -/** - * Find the closest point on a plane. - * - * \param r_close: Return coordinate - * \param plane: The plane to test against. - * \param pt: The point to find the nearest of - * - * \note non-unit-length planes are supported. - */ void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3]) { const float len_sq = len_squared_v3(plane); @@ -462,9 +414,6 @@ float dist_squared_to_plane3_v3(const float pt[3], const float plane[3]) return len_sq * (fac * fac); } -/** - * Return the signed distance from the point to the plane. - */ float dist_signed_to_plane_v3(const float pt[3], const float plane[4]) { const float len_sq = len_squared_v3(plane); @@ -489,7 +438,6 @@ float dist_to_plane3_v3(const float pt[3], const float plane[3]) return fabsf(dist_signed_to_plane3_v3(pt, plane)); } -/* distance v1 to line-piece l1-l2 in 3D */ float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]) { float closest[3]; @@ -517,29 +465,6 @@ float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3]) return sqrtf(dist_squared_to_line_v3(p, l1, l2)); } -/** - * Check if \a p is inside the 2x planes defined by `(v1, v2, v3)` - * where the 3x points define 2x planes. - * - * \param axis_ref: used when v1,v2,v3 form a line and to check if the corner is concave/convex. - * - * \note the distance from \a v1 & \a v3 to \a v2 doesn't matter - * (it just defines the planes). - * - * \return the lowest squared distance to either of the planes. - * where `(return < 0.0)` is outside. - * - * <pre> - * v1 - * + - * / - * x - out / x - inside - * / - * +----+ - * v2 v3 - * x - also outside - * </pre> - */ float dist_signed_squared_to_corner_v3v3v3(const float p[3], const float v1[3], const float v2[3], @@ -591,12 +516,6 @@ float dist_signed_squared_to_corner_v3v3v3(const float p[3], return max_ff(dist_a, dist_b); } -/** - * Compute the squared distance of a point to a line (defined as ray). - * \param ray_origin: A point on the line. - * \param ray_direction: Normalized direction of the line. - * \param co: Point to which the distance is to be calculated. - */ float dist_squared_to_ray_v3_normalized(const float ray_origin[3], const float ray_direction[3], const float co[3]) @@ -613,12 +532,6 @@ float dist_squared_to_ray_v3_normalized(const float ray_origin[3], return len_squared_v3v3(co, co_projected_on_ray); } -/** - * Find the closest point in a seg to a ray and return the distance squared. - * \param r_point: Is the point on segment closest to ray - * (or to ray_origin if the ray and the segment are parallel). - * \param r_depth: the distance of r_point projection on ray to the ray_origin. - */ float dist_squared_ray_to_seg_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], @@ -655,8 +568,6 @@ float dist_squared_ray_to_seg_v3(const float ray_origin[3], return len_squared_v3(dvec) - square_f(depth); } -/* Returns the coordinates of the nearest vertex and - * the farthest vertex from a plane (or normal). */ void aabb_get_near_far_from_plane(const float plane_no[3], const float bbmin[3], const float bbmax[3], @@ -707,9 +618,6 @@ void dist_squared_ray_to_aabb_v3_precalc(struct DistRayAABB_Precalc *neasrest_pr } } -/** - * Returns the distance from a ray to a bound-box (projected on ray) - */ float dist_squared_ray_to_aabb_v3(const struct DistRayAABB_Precalc *data, const float bb_min[3], const float bb_max[3], @@ -816,10 +724,6 @@ float dist_squared_ray_to_aabb_v3_simple(const float ray_origin[3], /** \name dist_squared_to_projected_aabb and helpers * \{ */ -/** - * \param projmat: Projection Matrix (usually perspective - * matrix multiplied by object matrix). - */ void dist_squared_to_projected_aabb_precalc(struct DistProjectedAABBPrecalc *precalc, const float projmat[4][4], const float winsize[2], @@ -871,7 +775,6 @@ void dist_squared_to_projected_aabb_precalc(struct DistProjectedAABBPrecalc *pre } } -/* Returns the distance from a 2d coordinate to a BoundBox (Projected) */ float dist_squared_to_projected_aabb(struct DistProjectedAABBPrecalc *data, const float bbmin[3], const float bbmax[3], @@ -1016,13 +919,12 @@ float dist_squared_to_projected_aabb_simple(const float projmat[4][4], } /** \} */ -/* Adapted from "Real-Time Collision Detection" by Christer Ericson, - * published by Morgan Kaufmann Publishers, copyright 2005 Elsevier Inc. - * - * Set 'r' to the point in triangle (a, b, c) closest to point 'p' */ void closest_on_tri_to_point_v3( float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3]) { + /* Adapted from "Real-Time Collision Detection" by Christer Ericson, + * published by Morgan Kaufmann Publishers, copyright 2005 Elsevier Inc. */ + float ab[3], ac[3], ap[3], d1, d2; float bp[3], d3, d4, vc, cp[3], d5, d6, vb, va; float denom, v, w; @@ -1100,7 +1002,6 @@ void closest_on_tri_to_point_v3( /******************************* Intersection ********************************/ -/* intersect Line-Line, shorts */ int isect_seg_seg_v2_int(const int v1[2], const int v2[2], const int v3[2], const int v4[2]) { float div, lambda, mu; @@ -1123,7 +1024,6 @@ int isect_seg_seg_v2_int(const int v1[2], const int v2[2], const int v3[2], cons return ISECT_LINE_LINE_NONE; } -/* intersect Line-Line, floats - gives intersection point */ int isect_line_line_v2_point( const float v0[2], const float v1[2], const float v2[2], const float v3[2], float r_vi[2]) { @@ -1147,7 +1047,6 @@ int isect_line_line_v2_point( return ISECT_LINE_LINE_COLINEAR; } -/* intersect Line-Line, floats */ int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) { float div, lambda, mu; @@ -1170,7 +1069,6 @@ int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], co return ISECT_LINE_LINE_NONE; } -/* Returns a point on each segment that is closest to the other. */ void isect_seg_seg_v3(const float a0[3], const float a1[3], const float b0[3], @@ -1236,19 +1134,6 @@ void isect_seg_seg_v3(const float a0[3], madd_v3_v3v3fl(r_b, b0, b_dir, fac_b); } -/** - * Get intersection point of two 2D segments. - * - * \param endpoint_bias: Bias to use when testing for end-point overlap. - * A positive value considers intersections that extend past the endpoints, - * negative values contract the endpoints. - * Note the bias is applied to a 0-1 factor, not scaled to the length of segments. - * - * \returns intersection type: - * - -1: collinear. - * - 1: intersection. - * - 0: no intersection. - */ int isect_seg_seg_v2_point_ex(const float v0[2], const float v1[2], const float v2[2], @@ -1369,18 +1254,6 @@ bool isect_seg_seg_v2_simple(const float v1[2], #undef CCW } -/** - * If intersection == ISECT_LINE_LINE_CROSS or ISECT_LINE_LINE_NONE: - * <pre> - * pt = v1 + lambda * (v2 - v1) = v3 + mu * (v4 - v3) - * </pre> - * \returns intersection type: - * - ISECT_LINE_LINE_COLINEAR: collinear. - * - ISECT_LINE_LINE_EXACT: intersection at an endpoint of either. - * - ISECT_LINE_LINE_CROSS: interaction, not at an endpoint. - * - ISECT_LINE_LINE_NONE: no intersection. - * Also returns lambda and mu in r_lambda and r_mu. - */ int isect_seg_seg_v2_lambda_mu_db(const double v1[2], const double v2[2], const double v3[2], @@ -1415,19 +1288,6 @@ int isect_seg_seg_v2_lambda_mu_db(const double v1[2], return ISECT_LINE_LINE_NONE; } -/** - * \param l1, l2: Coordinates (point of line). - * \param sp, r: Coordinate and radius (sphere). - * \return r_p1, r_p2: Intersection coordinates. - * - * \note The order of assignment for intersection points (\a r_p1, \a r_p2) is predictable, - * based on the direction defined by `l2 - l1`, - * this direction compared with the normal of each point on the sphere: - * \a r_p1 always has a >= 0.0 dot product. - * \a r_p2 always has a <= 0.0 dot product. - * For example, when \a l1 is inside the sphere and \a l2 is outside, - * \a r_p1 will always be between \a l1 and \a l2. - */ int isect_line_sphere_v3(const float l1[3], const float l2[3], const float sp[3], @@ -1490,7 +1350,6 @@ int isect_line_sphere_v3(const float l1[3], return -1; } -/* keep in sync with isect_line_sphere_v3 */ int isect_line_sphere_v2(const float l1[2], const float l2[2], const float sp[2], @@ -1498,6 +1357,8 @@ int isect_line_sphere_v2(const float l1[2], float r_p1[2], float r_p2[2]) { + /* Keep in sync with #isect_line_sphere_v3. */ + const float ldir[2] = {l2[0] - l1[0], l2[1] - l1[1]}; const float a = dot_v2v2(ldir, ldir); @@ -1537,12 +1398,13 @@ int isect_line_sphere_v2(const float l1[2], return -1; } -/* point in polygon (keep float and int versions in sync) */ bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr, const bool UNUSED(use_holes)) { + /* Keep in sync with #isect_point_poly_v2_int. */ + unsigned int i, j; bool isect = false; for (i = 0, j = nr - 1; i < nr; j = i++) { @@ -1560,6 +1422,8 @@ bool isect_point_poly_v2_int(const int pt[2], const unsigned int nr, const bool UNUSED(use_holes)) { + /* Keep in sync with #isect_point_poly_v2. */ + unsigned int i, j; bool isect = false; for (i = 0, j = nr - 1; i < nr; j = i++) { @@ -1575,7 +1439,6 @@ bool isect_point_poly_v2_int(const int pt[2], /* point in tri */ -/* only single direction */ bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], @@ -1612,7 +1475,6 @@ int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], return 0; } -/* point in quad - only convex quads */ int isect_point_quad_v2( const float pt[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2]) { @@ -1638,10 +1500,6 @@ int isect_point_quad_v2( return 0; } -/* moved from effect.c - * test if the line starting at p1 ending at p2 intersects the triangle v0..v2 - * return non zero if it does - */ bool isect_line_segment_tri_v3(const float p1[3], const float p2[3], const float v0[3], @@ -1692,7 +1550,6 @@ bool isect_line_segment_tri_v3(const float p1[3], return true; } -/* like isect_line_segment_tri_v3, but allows epsilon tolerance around triangle */ bool isect_line_segment_tri_epsilon_v3(const float p1[3], const float p2[3], const float v0[3], @@ -1744,10 +1601,6 @@ bool isect_line_segment_tri_epsilon_v3(const float p1[3], return true; } -/* moved from effect.c - * test if the ray starting at p1 going in d direction intersects the triangle v0..v2 - * return non zero if it does - */ bool isect_ray_tri_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], @@ -1799,12 +1652,6 @@ bool isect_ray_tri_v3(const float ray_origin[3], return true; } -/** - * if clip is nonzero, will only return true if lambda is >= 0.0 - * (i.e. intersection point is along positive \a ray_direction) - * - * \note #line_plane_factor_v3() shares logic. - */ bool isect_ray_plane_v3(const float ray_origin[3], const float ray_direction[3], const float plane[4], @@ -2146,9 +1993,6 @@ bool isect_ray_line_v3(const float ray_origin[3], return true; } -/** - * Check if a point is behind all planes. - */ bool isect_point_planes_v3(float (*planes)[4], int totplane, const float p[3]) { int i; @@ -2162,10 +2006,6 @@ bool isect_point_planes_v3(float (*planes)[4], int totplane, const float p[3]) return true; } -/** - * Check if a point is in front all planes. - * Same as isect_point_planes_v3 but with planes facing the opposite direction. - */ bool isect_point_planes_v3_negated(const float (*planes)[4], const int totplane, const float p[3]) { for (int i = 0; i < totplane; i++) { @@ -2177,17 +2017,6 @@ bool isect_point_planes_v3_negated(const float (*planes)[4], const int totplane, return true; } -/** - * Intersect line/plane. - * - * \param r_isect_co: The intersection point. - * \param l1: The first point of the line. - * \param l2: The second point of the line. - * \param plane_co: A point on the plane to intersect with. - * \param plane_no: The direction of the plane (does not need to be normalized). - * - * \note #line_plane_factor_v3() shares logic. - */ bool isect_line_plane_v3(float r_isect_co[3], const float l1[3], const float l2[3], @@ -2211,13 +2040,6 @@ bool isect_line_plane_v3(float r_isect_co[3], return false; } -/** - * Intersect three planes, return the point where all 3 meet. - * See Graphics Gems 1 pg 305 - * - * \param plane_a, plane_b, plane_c: Planes. - * \param r_isect_co: The resulting intersection point. - */ bool isect_plane_plane_plane_v3(const float plane_a[4], const float plane_b[4], const float plane_c[4], @@ -2251,17 +2073,6 @@ bool isect_plane_plane_plane_v3(const float plane_a[4], return false; } -/** - * Intersect two planes, return a point on the intersection and a vector - * that runs on the direction of the intersection. - * \note this is a slightly reduced version of #isect_plane_plane_plane_v3 - * - * \param plane_a, plane_b: Planes. - * \param r_isect_co: The resulting intersection point. - * \param r_isect_no: The resulting vector of the intersection. - * - * \note \a r_isect_no isn't unit length. - */ bool isect_plane_plane_v3(const float plane_a[4], const float plane_b[4], float r_isect_co[3], @@ -2296,19 +2107,6 @@ bool isect_plane_plane_v3(const float plane_a[4], return false; } -/** - * Intersect all planes, calling `callback_fn` for each point that intersects - * 3 of the planes that isn't outside any of the other planes. - * - * This can be thought of as calculating a convex-hull from an array of planes. - * - * \param eps_coplanar: Epsilon for testing if two planes are aligned (co-planar). - * \param eps_isect: Epsilon for testing of a point is behind any of the planes. - * - * \warning As complexity is a little under `O(N^3)`, this is only suitable for small arrays. - * - * \note This function could be optimized by some spatial structure. - */ bool isect_planes_v3_fn( const float planes[][4], const int planes_len, @@ -2371,16 +2169,6 @@ bool isect_planes_v3_fn( return found; } -/** - * Intersect two triangles. - * - * \param r_i1, r_i2: Retrieve the overlapping edge between the 2 triangles. - * \param r_tri_a_edge_isect_count: Indicates how many edges in the first triangle are intersected. - * \return true when the triangles intersect. - * - * \note If it exists, \a r_i1 will be a point on the edge of the 1st triangle. - * \note intersections between coplanar triangles are currently undetected. - */ bool isect_tri_tri_v3_ex(const float tri_a[3][3], const float tri_b[3][3], float r_i1[3], @@ -2755,14 +2543,6 @@ static bool getLowestRoot( return false; } -/** - * Checks status of an AABB in relation to a list of planes. - * - * \returns intersection type: - * - ISECT_AABB_PLANE_BEHIND_ONE (0): AABB is completely behind at least 1 plane; - * - ISECT_AABB_PLANE_CROSS_ANY (1): AABB intersects at least 1 plane; - * - ISECT_AABB_PLANE_IN_FRONT_ALL (2): AABB is completely in front of all planes; - */ int isect_aabb_planes_v3(const float (*planes)[4], const int totplane, const float bbmin[3], @@ -3030,12 +2810,6 @@ bool isect_axial_line_segment_tri_v3(const int axis, return true; } -/** - * \return The number of point of interests - * 0 - lines are collinear - * 1 - lines are coplanar, i1 is set to intersection - * 2 - i1 and i2 are the nearest points on line 1 (v1, v2) and line 2 (v3, v4) respectively - */ int isect_line_line_epsilon_v3(const float v1[3], const float v2[3], const float v3[3], @@ -3111,10 +2885,6 @@ int isect_line_line_v3(const float v1[3], return isect_line_line_epsilon_v3(v1, v2, v3, v4, r_i1, r_i2, epsilon); } -/** - * Intersection point strictly between the two lines - * \return false when no intersection is found. - */ bool isect_line_line_strict_v3(const float v1[3], const float v2[3], const float v3[3], @@ -3165,12 +2935,6 @@ bool isect_line_line_strict_v3(const float v1[3], return false; } -/** - * Check if two rays are not parallel and returns a factor that indicates - * the distance from \a ray_origin_b to the closest point on ray-a to ray-b. - * - * \note Neither directions need to be normalized. - */ bool isect_ray_ray_epsilon_v3(const float ray_origin_a[3], const float ray_direction_a[3], const float ray_origin_b[3], @@ -3247,12 +3011,13 @@ void isect_ray_aabb_v3_precalc(struct IsectRayAABB_Precalc *data, data->sign[2] = data->ray_inv_dir[2] < 0.0f; } -/* Adapted from http://www.gamedev.net/community/forums/topic.asp?topic_id=459973 */ bool isect_ray_aabb_v3(const struct IsectRayAABB_Precalc *data, const float bb_min[3], const float bb_max[3], float *tmin_out) { + /* Adapted from http://www.gamedev.net/community/forums/topic.asp?topic_id=459973 */ + float bbox[2][3]; copy_v3_v3(bbox[0], bb_min); @@ -3298,13 +3063,6 @@ bool isect_ray_aabb_v3(const struct IsectRayAABB_Precalc *data, return true; } -/** - * Test a bounding box (AABB) for ray intersection. - * Assumes the ray is already local to the boundbox space. - * - * \note \a direction should be normalized - * if you intend to use the \a tmin or \a tmax distance results! - */ bool isect_ray_aabb_v3_simple(const float orig[3], const float dir[3], const float bb_min[3], @@ -3357,10 +3115,6 @@ float closest_to_ray_v3(float r_close[3], return lambda; } -/** - * Find closest point to p on line through (l1, l2) and return lambda, - * where (0 <= lambda <= 1) when cp is in the line segment (l1, l2). - */ float closest_to_line_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3]) { float u[3]; @@ -3424,13 +3178,6 @@ float ray_point_factor_v3(const float p[3], return ray_point_factor_v3_ex(p, ray_origin, ray_direction, 0.0f, 0.0f); } -/** - * A simplified version of #closest_to_line_v3 - * we only need to return the `lambda` - * - * \param epsilon: avoid approaching divide-by-zero. - * Passing a zero will just check for nonzero division. - */ float line_point_factor_v3_ex(const float p[3], const float l1[3], const float l2[3], @@ -3471,9 +3218,6 @@ float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2 return line_point_factor_v2_ex(p, l1, l2, 0.0f, 0.0f); } -/** - * \note #isect_line_plane_v3() shares logic - */ float line_plane_factor_v3(const float plane_co[3], const float plane_no[3], const float l1[3], @@ -3487,10 +3231,6 @@ float line_plane_factor_v3(const float plane_co[3], return (dot != 0.0f) ? -dot_v3v3(plane_no, h) / dot : 0.0f; } -/** - * Ensure the distance between these points is no greater than 'dist'. - * If it is, scale them both into the center. - */ void limit_dist_v3(float v1[3], float v2[3], const float dist) { const float dist_old = len_v3v3(v1, v2); @@ -3508,13 +3248,6 @@ void limit_dist_v3(float v1[3], float v2[3], const float dist) } } -/* - * x1,y2 - * | \ - * | \ .(a,b) - * | \ - * x1,y1-- x2,y1 - */ int isect_point_tri_v2_int( const int x1, const int y1, const int x2, const int y2, const int a, const int b) { @@ -3603,12 +3336,6 @@ bool isect_point_tri_prism_v3(const float p[3], return true; } -/** - * \param r_isect_co: The point \a p projected onto the triangle. - * \return True when \a p is inside the triangle. - * \note Its up to the caller to check the distance between \a p and \a r_vi - * against an error margin. - */ bool isect_point_tri_v3( const float p[3], const float v1[3], const float v2[3], const float v3[3], float r_isect_co[3]) { @@ -3739,16 +3466,6 @@ bool clip_segment_v3_plane_n(const float p1[3], /****************************** Axis Utils ********************************/ -/** - * \brief Normal to x,y matrix - * - * Creates a 3x3 matrix from a normal. - * This matrix can be applied to vectors so their 'z' axis runs along \a normal. - * In practice it means you can use x,y as 2d coords. \see - * - * \param r_mat: The matrix to return. - * \param normal: A unit length vector. - */ void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3]) { BLI_ASSERT_UNIT_V3(normal); @@ -3766,9 +3483,6 @@ void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3]) is_zero_v3(normal)); } -/** - * Same as axis_dominant_v3_to_m3, but flips the normal - */ void axis_dominant_v3_to_m3_negate(float r_mat[3][3], const float normal[3]) { BLI_ASSERT_UNIT_V3(normal); @@ -3888,12 +3602,6 @@ void interp_weights_quad_v3(float w[4], } } -/** - * \return - * - 0 if the point is outside of triangle. - * - 1 if the point is inside triangle. - * - 2 if it's on the edge. - */ int barycentric_inside_triangle_v2(const float w[3]) { if (IN_RANGE(w[0], 0.0f, 1.0f) && IN_RANGE(w[1], 0.0f, 1.0f) && IN_RANGE(w[2], 0.0f, 1.0f)) { @@ -3907,9 +3615,6 @@ int barycentric_inside_triangle_v2(const float w[3]) return 0; } -/** - * \return false for degenerated triangles. - */ bool barycentric_coords_v2( const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]) { @@ -3934,12 +3639,6 @@ bool barycentric_coords_v2( return false; } -/** - * \note Using #cross_tri_v2 means locations outside the triangle are correctly weighted. - * - * \note This is *exactly* the same calculation as #resolve_tri_uv_v2, - * although it has double precision and is used for texture baking, so keep both. - */ void barycentric_weights_v2( const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]) { @@ -3963,11 +3662,6 @@ void barycentric_weights_v2( copy_v3_fl(w, 1.0f / 3.0f); } -/** - * A version of #barycentric_weights_v2 that doesn't allow negative weights. - * Useful when negative values cause problems and points are only - * ever slightly outside of the triangle. - */ void barycentric_weights_v2_clamped( const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]) { @@ -3991,10 +3685,6 @@ void barycentric_weights_v2_clamped( copy_v3_fl(w, 1.0f / 3.0f); } -/** - * still use 2D X,Y space but this works for verts transformed by a perspective matrix, - * using their 4th component as a weight - */ void barycentric_weights_v2_persp( const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3]) { @@ -4018,11 +3708,6 @@ void barycentric_weights_v2_persp( copy_v3_fl(w, 1.0f / 3.0f); } -/** - * same as #barycentric_weights_v2 but works with a quad, - * NOTE: untested for values outside the quad's bounds - * this is #interp_weights_poly_v2 expanded for quads only - */ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], @@ -4116,9 +3801,6 @@ void barycentric_weights_v2_quad(const float v1[2], } } -/* given 2 triangles in 3D space, and a point in relation to the first triangle. - * calculate the location of a point in relation to the second triangle. - * Useful for finding relative positions with geometry */ void transform_point_by_tri_v3(float pt_tar[3], float const pt_src[3], const float tri_tar_p1[3], @@ -4163,10 +3845,6 @@ void transform_point_by_tri_v3(float pt_tar[3], madd_v3_v3v3fl(pt_tar, pt_tar, no_tar, (z_ofs_src / area_src) * area_tar); } -/** - * Simply re-interpolates, - * assumes p_src is between \a l_src_p1-l_src_p2 - */ void transform_point_by_seg_v3(float p_dst[3], const float p_src[3], const float l_dst_p1[3], @@ -4178,8 +3856,6 @@ void transform_point_by_seg_v3(float p_dst[3], interp_v3_v3v3(p_dst, l_dst_p1, l_dst_p2, t); } -/* given an array with some invalid values this function interpolates valid values - * replacing the invalid ones */ int interp_sparse_array(float *array, const int list_size, const float skipval) { int found_invalid = 0; @@ -4516,7 +4192,6 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ /** \} */ -/* (x1, v1)(t1=0)------(x2, v2)(t2=1), 0<t<1 --> (x, v)(t) */ void interp_cubic_v3(float x[3], float v[3], const float x1[3], @@ -4552,13 +4227,6 @@ void interp_cubic_v3(float x[3], #define IS_ZERO(x) ((x > (-DBL_EPSILON) && x < DBL_EPSILON) ? 1 : 0) -/** - * Barycentric reverse - * - * Compute coordinates (u, v) for point \a st with respect to triangle (\a st0, \a st1, \a st2) - * - * \note same basic result as #barycentric_weights_v2, see its comment for details. - */ void resolve_tri_uv_v2( float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]) { @@ -4581,11 +4249,6 @@ void resolve_tri_uv_v2( } } -/** - * Barycentric reverse 3d - * - * Compute coordinates (u, v) for point \a st with respect to triangle (\a st0, \a st1, \a st2) - */ void resolve_tri_uv_v3( float r_uv[2], const float st[3], const float st0[3], const float st1[3], const float st2[3]) { @@ -4617,7 +4280,6 @@ void resolve_tri_uv_v3( } } -/* bilinear reverse */ void resolve_quad_uv_v2(float r_uv[2], const float st[2], const float st0[2], @@ -4628,7 +4290,6 @@ void resolve_quad_uv_v2(float r_uv[2], resolve_quad_uv_v2_deriv(r_uv, NULL, st, st0, st1, st2, st3); } -/* bilinear reverse with derivatives */ void resolve_quad_uv_v2_deriv(float r_uv[2], float r_deriv[2][2], const float st[2], @@ -4719,7 +4380,6 @@ void resolve_quad_uv_v2_deriv(float r_uv[2], } } -/* a version of resolve_quad_uv_v2 that only calculates the 'u' */ float resolve_quad_u_v2(const float st[2], const float st0[2], const float st1[2], @@ -4763,7 +4423,6 @@ float resolve_quad_u_v2(const float st[2], #undef IS_ZERO -/* reverse of the functions above */ void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3]) { float vec[3]; @@ -4797,9 +4456,6 @@ void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3]) /***************************** View & Projection *****************************/ -/** - * Matches `glOrtho` result. - */ void orthographic_m4(float matrix[4][4], const float left, const float right, @@ -4825,9 +4481,6 @@ void orthographic_m4(float matrix[4][4], matrix[3][2] = -(farClip + nearClip) / Zdelta; } -/** - * Matches `glFrustum` result. - */ void perspective_m4(float mat[4][4], const float left, const float right, @@ -4873,8 +4526,6 @@ void perspective_m4_fov(float mat[4][4], mat[1][1] /= nearClip; } -/* translate a matrix created by orthographic_m4 or perspective_m4 in XY coords - * (used to jitter the view) */ void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x, const float y) { if (winmat[2][3] == -1.0f) { @@ -4903,12 +4554,6 @@ void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x } } -/** - * Frustum planes extraction from a projection matrix - * (homogeneous 4d vector representations of planes). - * - * plane parameters can be NULL if you do not need them. - */ void planes_from_projmat(const float mat[4][4], float left[4], float right[4], @@ -5021,14 +4666,6 @@ void projmat_dimensions_db(const float winmat_fl[4][4], } } -/** - * Creates a projection matrix for a small region of the viewport. - * - * \param projmat: Projection Matrix. - * \param win_size: Viewport Size. - * \param x_min, x_max, y_min, y_max: Coordinates of the subregion. - * \return r_projmat: Resulting Projection Matrix. - */ void projmat_from_subregion(const float projmat[4][4], const int win_size[2], const int x_min, @@ -5363,8 +5000,6 @@ void accumulate_vertex_normals_v3(float n1[3], } } -/* Add weighted face normal component into normals of the face vertices. - * Caller must pass pre-allocated vdiffs of nverts length. */ void accumulate_vertex_normals_poly_v3(float **vertnos, const float polyno[3], const float **vertcos, @@ -5444,25 +5079,6 @@ void tangent_from_uv_v3(const float uv1[2], /****************************** Vector Clouds ********************************/ /* vector clouds */ -/** - * input - * - * \param list_size: 4 lists as pointer to array[list_size] - * \param pos: current pos array of 'new' positions - * \param weight: current weight array of 'new'weights (may be NULL pointer if you have no weights) - * \param rpos: Reference rpos array of 'old' positions - * \param rweight: Reference rweight array of 'old'weights - * (may be NULL pointer if you have no weights). - * - * output - * - * \param lloc: Center of mass pos. - * \param rloc: Center of mass rpos. - * \param lrot: Rotation matrix. - * \param lscale: Scale matrix. - * - * pointers may be NULL if not needed - */ void vcloud_estimate_transform_v3(const int list_size, const float (*pos)[3], @@ -6057,11 +5673,6 @@ float form_factor_hemi_poly( return contrib; } -/** - * Check if the edge is convex or concave - * (depends on face winding) - * Copied from BM_edge_is_convex(). - */ bool is_edge_convex_v3(const float v1[3], const float v2[3], const float f1_no[3], @@ -6078,9 +5689,6 @@ bool is_edge_convex_v3(const float v1[3], return false; } -/** - * Evaluate if entire quad is a proper convex quad - */ bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]) { /** @@ -6176,12 +5784,6 @@ bool is_poly_convex_v2(const float verts[][2], unsigned int nr) return true; } -/** - * Check if either of the diagonals along this quad create flipped triangles - * (normals pointing away from eachother). - * - (1 << 0): (v1-v3) is flipped. - * - (1 << 1): (v2-v4) is flipped. - */ int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]) { float d_12[3], d_23[3], d_34[3], d_41[3]; @@ -6232,14 +5834,6 @@ bool is_quad_flip_v3_first_third_fast_with_normal(const float v1[3], return (dot_v3v3(v4, tangent) >= dot) || (dot_v3v3(v2, tangent) <= dot); } -/** - * Return the value which the distance between points will need to be scaled by, - * to define a handle, given both points are on a perfect circle. - * - * Use when we want a bezier curve to match a circle as closely as possible. - * - * \note the return value will need to be divided by 0.75 for correct results. - */ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3]) { BLI_ASSERT_UNIT_V3(tan_l); @@ -6267,14 +5861,6 @@ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3]) return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin; } -/** - * Utility for computing approximate geodesic distances on triangle meshes. - * - * Given triangle with vertex coordinates v0, v1, v2, and known geodesic distances - * dist1 and dist2 at v1 and v2, estimate a geodesic distance at vertex v0. - * - * From "Dart Throwing on Surfaces", EGSR 2009. Section 7, Geodesic Dart Throwing. - */ float geodesic_distance_propagate_across_triangle( const float v0[3], const float v1[3], const float v2[3], const float dist1, const float dist2) { diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c index 857cbfbde9c..09028a1eb9a 100644 --- a/source/blender/blenlib/intern/math_geom_inline.c +++ b/source/blender/blenlib/intern/math_geom_inline.c @@ -164,7 +164,6 @@ MINLINE void madd_sh_shfl(float r[9], const float sh[9], const float f) add_sh_shsh(r, r, tmp); } -/* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */ MINLINE void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]) { const float xn = fabsf(axis[0]); @@ -185,7 +184,6 @@ MINLINE void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]) } } -/* same as axis_dominant_v3 but return the max value */ MINLINE float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3]) { const float xn = fabsf(axis[0]); @@ -209,7 +207,6 @@ MINLINE float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axi } } -/* get the single dominant axis value, 0==X, 1==Y, 2==Z */ MINLINE int axis_dominant_v3_single(const float vec[3]) { const float x = fabsf(vec[0]); @@ -218,7 +215,6 @@ MINLINE int axis_dominant_v3_single(const float vec[3]) return ((x > y) ? ((x > z) ? 0 : 2) : ((y > z) ? 1 : 2)); } -/* the dominant axis of an orthogonal vector */ MINLINE int axis_dominant_v3_ortho_single(const float vec[3]) { const float x = fabsf(vec[0]); @@ -243,15 +239,6 @@ MINLINE int min_axis_v3(const float vec[3]) return ((x < y) ? ((x < z) ? 0 : 2) : ((y < z) ? 1 : 2)); } -/** - * Simple function to either: - * - Calculate how many triangles needed from the total number of polygons + loops. - * - Calculate the first triangle index from the polygon index & that polygons loop-start. - * - * \param poly_count: The number of polygons or polygon-index - * (3+ sided faces, 1-2 sided give incorrect results). - * \param corner_count: The number of corners (also called loop-index). - */ MINLINE int poly_to_tri_count(const int poly_count, const int corner_count) { BLI_assert(!poly_count || corner_count > poly_count * 2); @@ -263,17 +250,10 @@ MINLINE float plane_point_side_v3(const float plane[4], const float co[3]) return dot_v3v3(co, plane) + plane[3]; } -/* useful to calculate an even width shell, by taking the angle between 2 planes. - * The return value is a scale on the offset. - * no angle between planes is 1.0, as the angle between the 2 planes approaches 180d - * the distance gets very high, 180d would be inf, but this case isn't valid */ MINLINE float shell_angle_to_dist(const float angle) { return (UNLIKELY(angle < SMALL_NUMBER)) ? 1.0f : fabsf(1.0f / cosf(angle)); } -/** - * Equivalent to `shell_angle_to_dist(angle_normalized_v3v3(a, b))`. - */ MINLINE float shell_v3v3_normalized_to_dist(const float a[3], const float b[3]) { const float angle_cos = fabsf(dot_v3v3(a, b)); @@ -281,9 +261,6 @@ MINLINE float shell_v3v3_normalized_to_dist(const float a[3], const float b[3]) BLI_ASSERT_UNIT_V3(b); return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos); } -/** - * Equivalent to `shell_angle_to_dist(angle_normalized_v2v2(a, b))`. - */ MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2]) { const float angle_cos = fabsf(dot_v2v2(a, b)); @@ -292,9 +269,6 @@ MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2]) return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos); } -/** - * Equivalent to `shell_angle_to_dist(angle_normalized_v3v3(a, b) / 2)`. - */ MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[3]) { float angle_cos; @@ -306,9 +280,6 @@ MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[ return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos); } -/** - * Equivalent to `shell_angle_to_dist(angle_normalized_v2v2(a, b) / 2)`. - */ MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[2]) { float angle_cos; diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c index bd48edf70c0..54beb74abca 100644 --- a/source/blender/blenlib/intern/math_interp.c +++ b/source/blender/blenlib/intern/math_interp.c @@ -567,10 +567,11 @@ static void radangle2imp(float a2, float b2, float th, float *A, float *B, float *F = a2 * b2; } -/* all tests here are done to make sure possible overflows are hopefully minimized */ void BLI_ewa_imp2radangle( float A, float B, float C, float F, float *a, float *b, float *th, float *ecc) { + /* NOTE: all tests here are done to make sure possible overflows are hopefully minimized. */ + if (F <= 1e-5f) { /* use arbitrary major radius, zero minor, infinite eccentricity */ *a = sqrtf(A > C ? A : C); *b = 0.0f; diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index b6d80d76be1..e562ed8c1f5 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -469,7 +469,6 @@ void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3]) R[2][2] = B_[2][0] * A_[0][2] + B_[2][1] * A_[1][2] + B_[2][2] * A_[2][2]; } -/* R = A * B, ignore the elements on the 4th row/column of A */ void mul_m3_m3m4(float R[3][3], const float A[3][3], const float B[4][4]) { float B_[4][4], A_[3][3]; @@ -493,7 +492,6 @@ void mul_m3_m3m4(float R[3][3], const float A[3][3], const float B[4][4]) R[2][2] = B_[2][0] * A_[0][2] + B_[2][1] * A_[1][2] + B_[2][2] * A_[2][2]; } -/* R = A * B, ignore the elements on the 4th row/column of B */ void mul_m3_m4m3(float R[3][3], const float A[4][4], const float B[3][3]) { float B_[3][3], A_[4][4]; @@ -805,7 +803,6 @@ void mul_m2_v2(const float mat[2][2], float vec[2]) mul_v2_m2v2(vec, mat, vec); } -/** Same as #mul_m4_v3() but doesn't apply translation component. */ void mul_mat3_m4_v3(const float M[4][4], float r[3]) { const float x = r[0]; @@ -1215,16 +1212,6 @@ bool invert_m4(float m[4][4]) return success; } -/** - * Computes the inverse of mat and puts it in inverse. - * Uses Gaussian Elimination with partial (maximal column) pivoting. - * \return true on success (i.e. can always find a pivot) and false on failure. - * Mark Segal - 1992. - * - * \note this has worse performance than #EIG_invert_m4_m4 (Eigen), but e.g. - * for non-invertible scale matrices, finding a partial solution can - * be useful to have a valid local transform center, see T57767. - */ bool invert_m4_m4_fallback(float inverse[4][4], const float mat[4][4]) { #ifndef MATH_STANDALONE @@ -1308,14 +1295,6 @@ bool invert_m4_m4(float inverse[4][4], const float mat[4][4]) #endif } -/** - * Combines transformations, handling scale separately in a manner equivalent - * to the Aligned Inherit Scale mode, in order to avoid creating shear. - * If A scale is uniform, the result is equivalent to ordinary multiplication. - * - * NOTE: this effectively takes output location from simple multiplication, - * and uses mul_m4_m4m4_split_channels for rotation and scale. - */ void mul_m4_m4m4_aligned_scale(float R[4][4], const float A[4][4], const float B[4][4]) { float loc_a[3], rot_a[3][3], size_a[3]; @@ -1332,9 +1311,6 @@ void mul_m4_m4m4_aligned_scale(float R[4][4], const float A[4][4], const float B loc_rot_size_to_mat4(R, loc_r, rot_r, size_r); } -/** - * Separately combines location, rotation and scale of the input matrices. - */ void mul_m4_m4m4_split_channels(float R[4][4], const float A[4][4], const float B[4][4]) { float loc_a[3], rot_a[3][3], size_a[3]; @@ -1383,7 +1359,6 @@ void transpose_m3_m3(float R[3][3], const float M[3][3]) R[2][2] = M[2][2]; } -/* seems obscure but in-fact a common operation */ void transpose_m3_m4(float R[3][3], const float M[4][4]) { BLI_assert(&R[0][0] != &M[0][0]); @@ -1461,11 +1436,6 @@ bool compare_m4m4(const float mat1[4][4], const float mat2[4][4], float limit) return false; } -/** - * Make an orthonormal matrix around the selected axis of the given matrix. - * - * \param axis: Axis to build the orthonormal basis around. - */ void orthogonalize_m3(float R[3][3], int axis) { float size[3]; @@ -1550,11 +1520,6 @@ void orthogonalize_m3(float R[3][3], int axis) mul_v3_fl(R[2], size[2]); } -/** - * Make an orthonormal matrix around the selected axis of the given matrix. - * - * \param axis: Axis to build the orthonormal basis around. - */ void orthogonalize_m4(float R[4][4], int axis) { float size[3]; @@ -1692,14 +1657,6 @@ static void orthogonalize_stable(float v1[3], float v2[3], float v3[3], bool nor } } -/** - * Make an orthonormal matrix around the selected axis of the given matrix, - * in a way that is symmetric and stable to variations in the input, and - * preserving the value of the determinant, i.e. the overall volume change. - * - * \param axis: Axis to build the orthonormal basis around. - * \param normalize: Normalize the matrix instead of preserving volume. - */ void orthogonalize_m3_stable(float R[3][3], int axis, bool normalize) { switch (axis) { @@ -1718,14 +1675,6 @@ void orthogonalize_m3_stable(float R[3][3], int axis, bool normalize) } } -/** - * Make an orthonormal matrix around the selected axis of the given matrix, - * in a way that is symmetric and stable to variations in the input, and - * preserving the value of the determinant, i.e. the overall volume change. - * - * \param axis: Axis to build the orthonormal basis around. - * \param normalize: Normalize the matrix instead of preserving volume. - */ void orthogonalize_m4_stable(float R[4][4], int axis, bool normalize) { switch (axis) { @@ -2193,10 +2142,6 @@ void mat4_to_size(float size[3], const float M[4][4]) size[2] = len_v3(M[2]); } -/** - * Extract scale factors from the matrix, with correction to ensure - * exact volume in case of a sheared matrix. - */ void mat4_to_size_fix_shear(float size[3], const float M[4][4]) { mat4_to_size(size, M); @@ -2208,11 +2153,6 @@ void mat4_to_size_fix_shear(float size[3], const float M[4][4]) } } -/** - * This computes the overall volume scale factor of a transformation matrix. - * For an orthogonal matrix, it is the product of all three scale values. - * Returns a negative value if the transform is flipped by negative scale. - */ float mat3_to_volume_scale(const float mat[3][3]) { return determinant_m3_array(mat); @@ -2223,11 +2163,6 @@ float mat4_to_volume_scale(const float mat[4][4]) return determinant_m4_mat3_array(mat); } -/** - * This gets the average scale of a matrix, only use when your scaling - * data that has no idea of scale axis, examples are bone-envelope-radius - * and curve radius. - */ float mat3_to_scale(const float mat[3][3]) { /* unit length vector */ @@ -2246,7 +2181,6 @@ float mat4_to_scale(const float mat[4][4]) return len_v3(unit_vec); } -/** Return 2D scale (in XY plane) of given mat4. */ float mat4_to_xy_scale(const float M[4][4]) { /* unit length vector in xy plane */ @@ -2367,14 +2301,6 @@ void translate_m4(float mat[4][4], float Tx, float Ty, float Tz) mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]); } -/* TODO: enum for axis? */ -/** - * Rotate a matrix in-place. - * - * \note To create a new rotation matrix see: - * #axis_angle_to_mat4_single, #axis_angle_to_mat3_single, #angle_to_mat2 - * (axis & angle args are compatible). - */ void rotate_m4(float mat[4][4], const char axis, const float angle) { const float angle_cos = cosf(angle); @@ -2412,7 +2338,6 @@ void rotate_m4(float mat[4][4], const char axis, const float angle) } } -/** Scale a matrix in-place. */ void rescale_m4(float mat[4][4], const float scale[3]) { mul_v3_fl(mat[0], scale[0]); @@ -2420,14 +2345,6 @@ void rescale_m4(float mat[4][4], const float scale[3]) mul_v3_fl(mat[2], scale[2]); } -/** - * Scale or rotate around a pivot point, - * a convenience function to avoid having to do inline. - * - * Since its common to make a scale/rotation matrix that pivots around an arbitrary point. - * - * Typical use case is to make 3x3 matrix, copy to 4x4, then pass to this function. - */ void transform_pivot_set_m4(float mat[4][4], const float pivot[3]) { float tmat[4][4]; @@ -2495,22 +2412,6 @@ void blend_m4_m4m4(float out[4][4], /* for builds without Eigen */ #ifndef MATH_STANDALONE -/** - * A polar-decomposition-based interpolation between matrix A and matrix B. - * - * \note This code is about five times slower as the 'naive' interpolation done by #blend_m3_m3m3 - * (it typically remains below 2 usec on an average i74700, - * while #blend_m3_m3m3 remains below 0.4 usec). - * However, it gives expected results even with non-uniformly scaled matrices, - * see T46418 for an example. - * - * Based on "Matrix Animation and Polar Decomposition", by Ken Shoemake & Tom Duff - * - * \param R: Resulting interpolated matrix. - * \param A: Input matrix which is totally effective with `t = 0.0`. - * \param B: Input matrix which is totally effective with `t = 1.0`. - * \param t: Interpolation factor. - */ void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t) { /* 'Rotation' component ('U' part of polar decomposition, @@ -2556,15 +2457,6 @@ void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], con mul_m3_m3m3(R, U, P); } -/** - * Complete transform matrix interpolation, - * based on polar-decomposition-based interpolation from #interp_m3_m3m3. - * - * \param R: Resulting interpolated matrix. - * \param A: Input matrix which is totally effective with `t = 0.0`. - * \param B: Input matrix which is totally effective with `t = 1.0`. - * \param t: Interpolation factor. - */ void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t) { float A3[3][3], B3[3][3], R3[3][3]; @@ -2621,10 +2513,6 @@ bool equals_m4m4(const float mat1[4][4], const float mat2[4][4]) equals_v4v4(mat1[2], mat2[2]) && equals_v4v4(mat1[3], mat2[3])); } -/** - * Make a 4x4 matrix out of 3 transform components. - * Matrices are made in the order: `scale * rot * loc` - */ void loc_rot_size_to_mat4(float R[4][4], const float loc[3], const float rot[3][3], @@ -2635,12 +2523,6 @@ void loc_rot_size_to_mat4(float R[4][4], copy_v3_v3(R[3], loc); } -/** - * Make a 4x4 matrix out of 3 transform components. - * Matrices are made in the order: `scale * rot * loc` - * - * TODO: need to have a version that allows for rotation order... - */ void loc_eul_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], @@ -2665,10 +2547,6 @@ void loc_eul_size_to_mat4(float R[4][4], R[3][2] = loc[2]; } -/** - * Make a 4x4 matrix out of 3 transform components. - * Matrices are made in the order: `scale * rot * loc` - */ void loc_eulO_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], @@ -2694,10 +2572,6 @@ void loc_eulO_size_to_mat4(float R[4][4], R[3][2] = loc[2]; } -/** - * Make a 4x4 matrix out of 3 transform components. - * Matrices are made in the order: `scale * rot * loc` - */ void loc_quat_size_to_mat4(float R[4][4], const float loc[3], const float quat[4], @@ -2751,18 +2625,11 @@ void print_m4(const char *str, const float m[4][4]) printf("\n"); } -/*********************************** SVD ************************************ - * from TNT matrix library - * - * Compute the Single Value Decomposition of an arbitrary matrix A - * That is compute the 3 matrices U,W,V with U column orthogonal (m,n) - * ,W a diagonal matrix and V an orthogonal square matrix `s.t.A = U.W.Vt`. - * From this decomposition it is trivial to compute the (pseudo-inverse) - * of `A` as `Ainv = V.Winv.transpose(U)`. - */ - void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4]) { + /* NOTE: originally from TNT (template numeric toolkit) matrix library. + * https://math.nist.gov/tnt */ + float A[4][4]; float work1[4], work2[4]; int m = 4; @@ -3269,12 +3136,6 @@ void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4]) * where we want to specify the length of the degenerate axes. * \{ */ -/** - * A safe version of invert that uses valid axes, calculating the zero'd axis - * based on the non-zero ones. - * - * This works well for transformation matrices, when a single axis is zerod. - */ void invert_m4_m4_safe_ortho(float Ainv[4][4], const float A[4][4]) { if (UNLIKELY(!invert_m4_m4(Ainv, A))) { @@ -3299,37 +3160,6 @@ void invert_m3_m3_safe_ortho(float Ainv[3][3], const float A[3][3]) /** \} */ -/** - * #SpaceTransform struct encapsulates all needed data to convert between two coordinate spaces - * (where conversion can be represented by a matrix multiplication). - * - * A SpaceTransform is initialized using: - * - #BLI_SPACE_TRANSFORM_SETUP(&data, ob1, ob2) - * - * After that the following calls can be used: - * - Converts a coordinate in ob1 space to the corresponding ob2 space: - * #BLI_space_transform_apply(&data, co); - * - Converts a coordinate in ob2 space to the corresponding ob1 space: - * #BLI_space_transform_invert(&data, co); - * - * Same concept as #BLI_space_transform_apply and #BLI_space_transform_invert, - * but no is normalized after conversion (and not translated at all!): - * - #BLI_space_transform_apply_normal(&data, no); - * - #BLI_space_transform_invert_normal(&data, no); - */ - -/** - * Global-invariant transform. - * - * This defines a matrix transforming a point in local space to a point in target space - * such that its global coordinates remain unchanged. - * - * In other words, if we have a global point P with local coordinates (x, y, z) - * and global coordinates (X, Y, Z), - * this defines a transform matrix TM such that (x', y', z') = TM * (x, y, z) - * where (x', y', z') are the coordinates of P' in target space - * such that it keeps (X, Y, Z) coordinates in global space. - */ void BLI_space_transform_from_matrices(SpaceTransform *data, const float local[4][4], const float target[4][4]) @@ -3340,18 +3170,6 @@ void BLI_space_transform_from_matrices(SpaceTransform *data, invert_m4_m4(data->target2local, data->local2target); } -/** - * Local-invariant transform. - * - * This defines a matrix transforming a point in global space - * such that its local coordinates (from local space to target space) remain unchanged. - * - * In other words, if we have a local point p with local coordinates (x, y, z) - * and global coordinates (X, Y, Z), - * this defines a transform matrix TM such that (X', Y', Z') = TM * (X, Y, Z) - * where (X', Y', Z') are the coordinates of p' in global space - * such that it keeps (x, y, z) coordinates in target space. - */ void BLI_space_transform_global_from_matrices(SpaceTransform *data, const float local[4][4], const float target[4][4]) diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 34baac6f2a4..dbcf3a6500c 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -34,7 +34,6 @@ # define QUAT_EPSILON 0.0001 #endif -/* convenience, avoids setting Y axis everywhere */ void unit_axis_angle(float axis[3], float *angle) { axis[0] = 0.0f; @@ -75,25 +74,6 @@ void mul_qt_qtqt(float q[4], const float a[4], const float b[4]) q[2] = t2; } -/** - * \note - * Assumes a unit quaternion? - * - * in fact not, but you may want to use a unit quat, read on... - * - * Shortcut for 'q v q*' when \a v is actually a quaternion. - * This removes the need for converting a vector to a quaternion, - * calculating q's conjugate and converting back to a vector. - * It also happens to be faster (17+,24* vs * 24+,32*). - * If \a q is not a unit quaternion, then \a v will be both rotated by - * the same amount as if q was a unit quaternion, and scaled by the square of - * the length of q. - * - * For people used to python mathutils, its like: - * def mul_qt_v3(q, v): (q * Quaternion((0.0, v[0], v[1], v[2])) * q.conjugated())[1:] - * - * \note Multiplying by 3x3 matrix is ~25% faster. - */ void mul_qt_v3(const float q[4], float r[3]) { float t0, t1, t2; @@ -150,11 +130,6 @@ void invert_qt_qt(float q1[4], const float q2[4]) invert_qt(q1); } -/** - * This is just conjugate_qt for cases we know \a q is unit-length. - * we could use #conjugate_qt directly, but use this function to show intent, - * and assert if its ever becomes non-unit-length. - */ void invert_qt_normalized(float q[4]) { BLI_ASSERT_UNIT_QUAT(q); @@ -167,7 +142,6 @@ void invert_qt_qt_normalized(float q1[4], const float q2[4]) invert_qt_normalized(q1); } -/* Simple multiply. */ void mul_qt_fl(float q[4], const float f) { q[0] *= f; @@ -188,7 +162,6 @@ void sub_qt_qtqt(float q[4], const float a[4], const float b[4]) mul_qt_qtqt(q, a, n_b); } -/* raise a unit quaternion to the specified power */ void pow_qt_fl_normalized(float q[4], const float fac) { BLI_ASSERT_UNIT_QUAT(q); @@ -200,10 +173,6 @@ void pow_qt_fl_normalized(float q[4], const float fac) normalize_v3_length(q + 1, si); } -/** - * Apply the rotation of \a a to \a q keeping the values compatible with \a old. - * Avoid axis flipping for animated f-curves for eg. - */ void quat_to_compatible_quat(float q[4], const float a[4], const float old[4]) { const float eps = 1e-4f; @@ -471,9 +440,6 @@ float normalize_qt_qt(float r[4], const float q[4]) return normalize_qt(r); } -/** - * Calculate a rotation matrix from 2 normalized vectors. - */ void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3]) { float axis[3]; @@ -511,7 +477,6 @@ void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float } } -/* NOTE: expects vectors to be normalized. */ void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]) { float axis[3]; @@ -551,16 +516,6 @@ void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q mul_qt_qtqt(q, tquat, q2); } -/** - * Decompose a quaternion into a swing rotation (quaternion with the selected - * axis component locked at zero), followed by a twist rotation around the axis. - * - * \param q: input quaternion. - * \param axis: twist axis in [0,1,2] - * \param r_swing: if not NULL, receives the swing quaternion. - * \param r_twist: if not NULL, receives the twist quaternion. - * \returns twist angle. - */ float quat_split_swing_and_twist(const float q_in[4], int axis, float r_swing[4], float r_twist[4]) { BLI_assert(axis >= 0 && axis <= 2); @@ -861,14 +816,6 @@ void QuatInterpolW(float *result, float quat1[4], float quat2[4], float t) } #endif -/** - * Generic function for implementing slerp - * (quaternions and spherical vector coords). - * - * \param t: factor in [0..1] - * \param cosom: dot product from normalized vectors/quats. - * \param r_w: calculated weights. - */ void interp_dot_slerp(const float t, const float cosom, float r_w[2]) { const float eps = 1e-4f; @@ -925,8 +872,6 @@ void add_qt_qtqt(float q[4], const float a[4], const float b[4], const float t) q[3] = a[3] + t * b[3]; } -/* same as tri_to_quat() but takes pre-computed normal from the triangle - * used for ngons when we know their normal */ void tri_to_quat_ex( float quat[4], const float v1[3], const float v2[3], const float v3[3], const float no_orig[3]) { @@ -979,9 +924,6 @@ void tri_to_quat_ex( mul_qt_qtqt(quat, q1, q2); } -/** - * \return the length of the normal, use to test for degenerate triangles. - */ float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3]) { float vec[3]; @@ -1020,7 +962,6 @@ void axis_angle_to_quat(float r[4], const float axis[3], const float angle) } } -/* Quaternions to Axis Angle */ void quat_to_axis_angle(float axis[3], float *angle, const float q[4]) { float ha, si; @@ -1054,7 +995,6 @@ void quat_to_axis_angle(float axis[3], float *angle, const float q[4]) } } -/* Axis Angle to Euler Rotation */ void axis_angle_to_eulO(float eul[3], const short order, const float axis[3], const float angle) { float q[4]; @@ -1064,7 +1004,6 @@ void axis_angle_to_eulO(float eul[3], const short order, const float axis[3], co quat_to_eulO(eul, order, q); } -/* Euler Rotation to Axis Angle */ void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], const short order) { float q[4]; @@ -1074,15 +1013,6 @@ void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], const s quat_to_axis_angle(axis, angle, q); } -/** - * axis angle to 3x3 matrix - * - * This takes the angle with sin/cos applied so we can avoid calculating it in some cases. - * - * \param axis: rotation axis (must be normalized). - * \param angle_sin: sin(angle) - * \param angle_cos: cos(angle) - */ void axis_angle_normalized_to_mat3_ex(float mat[3][3], const float axis[3], const float angle_sin, @@ -1123,7 +1053,6 @@ void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], const flo axis_angle_normalized_to_mat3_ex(R, axis, sinf(angle), cosf(angle)); } -/* axis angle to 3x3 matrix - safer version (normalization of axis performed) */ void axis_angle_to_mat3(float R[3][3], const float axis[3], const float angle) { float nor[3]; @@ -1137,7 +1066,6 @@ void axis_angle_to_mat3(float R[3][3], const float axis[3], const float angle) axis_angle_normalized_to_mat3(R, nor, angle); } -/* axis angle to 4x4 matrix - safer version (normalization of axis performed) */ void axis_angle_to_mat4(float R[4][4], const float axis[3], const float angle) { float tmat[3][3]; @@ -1147,7 +1075,6 @@ void axis_angle_to_mat4(float R[4][4], const float axis[3], const float angle) copy_m4_m3(R, tmat); } -/* 3x3 matrix to axis angle */ void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float mat[3][3]) { float q[4]; @@ -1167,7 +1094,6 @@ void mat3_to_axis_angle(float axis[3], float *angle, const float mat[3][3]) quat_to_axis_angle(axis, angle, q); } -/* 4x4 matrix to axis angle */ void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float mat[4][4]) { float q[4]; @@ -1178,7 +1104,6 @@ void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float mat[ quat_to_axis_angle(axis, angle, q); } -/* 4x4 matrix to axis angle */ void mat4_to_axis_angle(float axis[3], float *angle, const float mat[4][4]) { float q[4]; @@ -1196,7 +1121,6 @@ void axis_angle_to_mat4_single(float R[4][4], const char axis, const float angle copy_m4_m3(R, mat3); } -/* rotation matrix from a single axis */ void axis_angle_to_mat3_single(float R[3][3], const char axis, const float angle) { const float angle_cos = cosf(angle); @@ -1305,7 +1229,6 @@ void expmap_to_quat(float r[4], const float expmap[3]) /******************************** XYZ Eulers *********************************/ -/* XYZ order */ void eul_to_mat3(float mat[3][3], const float eul[3]) { double ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -1332,7 +1255,6 @@ void eul_to_mat3(float mat[3][3], const float eul[3]) mat[2][2] = (float)(cj * ci); } -/* XYZ order */ void eul_to_mat4(float mat[4][4], const float eul[3]) { double ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -1390,7 +1312,6 @@ static void mat3_normalized_to_eul2(const float mat[3][3], float eul1[3], float } } -/* XYZ order */ void mat3_normalized_to_eul(float eul[3], const float mat[3][3]) { float eul1[3], eul2[3]; @@ -1413,7 +1334,6 @@ void mat3_to_eul(float eul[3], const float mat[3][3]) mat3_normalized_to_eul(eul, unit_mat); } -/* XYZ order */ void mat4_normalized_to_eul(float eul[3], const float m[4][4]) { float mat3[3][3]; @@ -1427,7 +1347,6 @@ void mat4_to_eul(float eul[3], const float m[4][4]) mat3_to_eul(eul, mat3); } -/* XYZ order */ void quat_to_eul(float eul[3], const float quat[4]) { float unit_mat[3][3]; @@ -1435,7 +1354,6 @@ void quat_to_eul(float eul[3], const float quat[4]) mat3_normalized_to_eul(eul, unit_mat); } -/* XYZ order */ void eul_to_quat(float quat[4], const float eul[3]) { float ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -1460,7 +1378,6 @@ void eul_to_quat(float quat[4], const float eul[3]) quat[3] = cj * cs - sj * sc; } -/* XYZ order */ void rotate_eul(float beul[3], const char axis, const float ang) { float eul[3], mat1[3][3], mat2[3][3], totmat[3][3]; @@ -1486,7 +1403,6 @@ void rotate_eul(float beul[3], const char axis, const float ang) mat3_to_eul(beul, totmat); } -/* order independent! */ void compatible_eul(float eul[3], const float oldrot[3]) { /* we could use M_PI as pi_thresh: which is correct but 5.1 gives better results. @@ -1539,7 +1455,6 @@ void compatible_eul(float eul[3], const float oldrot[3]) /* uses 2 methods to retrieve eulers, and picks the closest */ -/* XYZ order */ void mat3_normalized_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]) { float eul1[3], eul2[3]; @@ -1622,7 +1537,6 @@ static const RotOrderInfo *get_rotation_order_info(const short order) return &rotOrders[5]; } -/* Construct quaternion from Euler angles (in radians). */ void eulO_to_quat(float q[4], const float e[3], const short order) { const RotOrderInfo *R = get_rotation_order_info(order); @@ -1660,7 +1574,6 @@ void eulO_to_quat(float q[4], const float e[3], const short order) } } -/* Convert quaternion to Euler angles (in radians). */ void quat_to_eulO(float e[3], short const order, const float q[4]) { float unit_mat[3][3]; @@ -1669,7 +1582,6 @@ void quat_to_eulO(float e[3], short const order, const float q[4]) mat3_normalized_to_eulO(e, order, unit_mat); } -/* Construct 3x3 matrix from Euler angles (in radians). */ void eulO_to_mat3(float M[3][3], const float e[3], const short order) { const RotOrderInfo *R = get_rotation_order_info(order); @@ -1747,7 +1659,6 @@ static void mat3_normalized_to_eulo2(const float mat[3][3], } } -/* Construct 4x4 matrix from Euler angles (in radians). */ void eulO_to_mat4(float mat[4][4], const float e[3], const short order) { float unit_mat[3][3]; @@ -1757,7 +1668,6 @@ void eulO_to_mat4(float mat[4][4], const float e[3], const short order) copy_m4_m3(mat, unit_mat); } -/* Convert 3x3 matrix to Euler angles (in radians). */ void mat3_normalized_to_eulO(float eul[3], const short order, const float m[3][3]) { float eul1[3], eul2[3]; @@ -1783,7 +1693,6 @@ void mat3_to_eulO(float eul[3], const short order, const float m[3][3]) mat3_normalized_to_eulO(eul, order, unit_mat); } -/* Convert 4x4 matrix to Euler angles (in radians). */ void mat4_normalized_to_eulO(float eul[3], const short order, const float m[4][4]) { float mat3[3][3]; @@ -1801,7 +1710,6 @@ void mat4_to_eulO(float eul[3], const short order, const float m[4][4]) mat3_normalized_to_eulO(eul, order, mat3); } -/* uses 2 methods to retrieve eulers, and picks the closest */ void mat3_normalized_to_compatible_eulO(float eul[3], const float oldrot[3], const short order, @@ -1901,7 +1809,6 @@ void rotate_eulO(float beul[3], const short order, char axis, float ang) mat3_to_eulO(beul, order, totmat); } -/* the matrix is written to as 3 axis vectors */ void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order) { const RotOrderInfo *R = get_rotation_order_info(order); @@ -2190,7 +2097,6 @@ void copy_dq_dq(DualQuat *r, const DualQuat *dq) memcpy(r, dq, sizeof(DualQuat)); } -/* axis matches eTrackToAxis_Modes */ void quat_apply_track(float quat[4], short axis, short upflag) { /* rotations are hard coded to match vec_to_quat */ @@ -2271,7 +2177,6 @@ void vec_apply_track(float vec[3], short axis) } } -/* lens/angle conversion (radians) */ float focallength_to_fov(float focal_length, float sensor) { return 2.0f * atanf((sensor / 2.0f) / focal_length); @@ -2298,7 +2203,6 @@ float angle_wrap_deg(float angle) return mod_inline(angle + 180.0f, 360.0f) - 180.0f; } -/* returns an angle compatible with angle_compat */ float angle_compat_rad(float angle, float angle_compat) { return angle_compat + angle_wrap_rad(angle - angle_compat); @@ -2387,10 +2291,6 @@ BLI_INLINE int _axis_signed(const int axis) return (axis < 3) ? axis : axis - 3; } -/** - * Each argument us an axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z'] - * where the first 2 are a source and the second 2 are the target. - */ bool mat3_from_axis_conversion( int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3]) { @@ -2423,9 +2323,6 @@ bool mat3_from_axis_conversion( return false; } -/** - * Use when the second axis can be guessed. - */ bool mat3_from_axis_conversion_single(int src_axis, int dst_axis, float r_mat[3][3]) { if (src_axis == dst_axis) { diff --git a/source/blender/blenlib/intern/math_solvers.c b/source/blender/blenlib/intern/math_solvers.c index 131afc19f28..f7630efd203 100644 --- a/source/blender/blenlib/intern/math_solvers.c +++ b/source/blender/blenlib/intern/math_solvers.c @@ -32,13 +32,6 @@ /********************************** Eigen Solvers *********************************/ -/** - * \brief Compute the eigen values and/or vectors of given 3D symmetric (aka adjoint) matrix. - * - * \param m3: the 3D symmetric matrix. - * \return r_eigen_values the computed eigen values (NULL if not needed). - * \return r_eigen_vectors the computed eigen vectors (NULL if not needed). - */ bool BLI_eigen_solve_selfadjoint_m3(const float m3[3][3], float r_eigen_values[3], float r_eigen_vectors[3][3]) @@ -54,14 +47,6 @@ bool BLI_eigen_solve_selfadjoint_m3(const float m3[3][3], 3, (const float *)m3, r_eigen_values, (float *)r_eigen_vectors); } -/** - * \brief Compute the SVD (Singular Values Decomposition) of given 3D matrix (m3 = USV*). - * - * \param m3: the matrix to decompose. - * \return r_U the computed left singular vector of \a m3 (NULL if not needed). - * \return r_S the computed singular values of \a m3 (NULL if not needed). - * \return r_V the computed right singular vector of \a m3 (NULL if not needed). - */ void BLI_svd_m3(const float m3[3][3], float r_U[3][3], float r_S[3], float r_V[3][3]) { EIG_svd_square_matrix(3, (const float *)m3, (float *)r_U, (float *)r_S, (float *)r_V); @@ -69,16 +54,6 @@ void BLI_svd_m3(const float m3[3][3], float r_U[3][3], float r_S[3], float r_V[3 /***************************** Simple Solvers ************************************/ -/** - * \brief Solve a tridiagonal system of equations: - * - * a[i] * r_x[i-1] + b[i] * r_x[i] + c[i] * r_x[i+1] = d[i] - * - * Ignores a[0] and c[count-1]. Uses the Thomas algorithm, e.g. see wiki. - * - * \param r_x: output vector, may be shared with any of the input ones - * \return true if success - */ bool BLI_tridiagonal_solve( const float *a, const float *b, const float *c, const float *d, float *r_x, const int count) { @@ -124,12 +99,6 @@ bool BLI_tridiagonal_solve( return isfinite(x_prev); } -/** - * \brief Solve a possibly cyclic tridiagonal system using the Sherman-Morrison formula. - * - * \param r_x: output vector, may be shared with any of the input ones - * \return true if success - */ bool BLI_tridiagonal_solve_cyclic( const float *a, const float *b, const float *c, const float *d, float *r_x, const int count) { @@ -194,21 +163,6 @@ bool BLI_tridiagonal_solve_cyclic( return success; } -/** - * \brief Solve a generic f(x) = 0 equation using Newton's method. - * - * \param func_delta: Callback computing the value of f(x). - * \param func_jacobian: Callback computing the Jacobian matrix of the function at x. - * \param func_correction: Callback for forcing the search into an arbitrary custom domain. - * May be NULL. - * \param userdata: Data for the callbacks. - * \param epsilon: Desired precision. - * \param max_iterations: Limit on the iterations. - * \param trace: Enables logging to console. - * \param x_init: Initial solution vector. - * \param result: Final result. - * \return true if success - */ bool BLI_newton3d_solve(Newton3D_DeltaFunc func_delta, Newton3D_JacobianFunc func_jacobian, Newton3D_CorrectionFunc func_correction, diff --git a/source/blender/blenlib/intern/math_statistics.c b/source/blender/blenlib/intern/math_statistics.c index b90ac99dbfe..8087e7a962a 100644 --- a/source/blender/blenlib/intern/math_statistics.c +++ b/source/blender/blenlib/intern/math_statistics.c @@ -87,18 +87,6 @@ static void covariance_m_vn_ex_task_cb(void *__restrict userdata, } } -/** - * \brief Compute the covariance matrix of given set of nD coordinates. - * - * \param n: the dimension of the vectors (and hence, of the covariance matrix to compute). - * \param cos_vn: the nD points to compute covariance from. - * \param nbr_cos_vn: the number of nD coordinates in cos_vn. - * \param center: the center (or mean point) of cos_vn. If NULL, - * it is assumed cos_vn is already centered. - * \param use_sample_correction: whether to apply sample correction - * (i.e. get 'sample variance' instead of 'population variance'). - * \return r_covmat the computed covariance matrix. - */ void BLI_covariance_m_vn_ex(const int n, const float *cos_vn, const int nbr_cos_vn, @@ -128,14 +116,6 @@ void BLI_covariance_m_vn_ex(const int n, BLI_task_parallel_range(0, n * n, &data, covariance_m_vn_ex_task_cb, &settings); } -/** - * \brief Compute the covariance matrix of given set of 3D coordinates. - * - * \param cos_v3: the 3D points to compute covariance from. - * \param nbr_cos_v3: the number of 3D coordinates in cos_v3. - * \return r_covmat the computed covariance matrix. - * \return r_center the computed center (mean) of 3D points (may be NULL). - */ void BLI_covariance_m3_v3n(const float (*cos_v3)[3], const int nbr_cos_v3, const bool use_sample_correction, diff --git a/source/blender/blenlib/intern/math_time.c b/source/blender/blenlib/intern/math_time.c index b85de7817dd..4484144a81e 100644 --- a/source/blender/blenlib/intern/math_time.c +++ b/source/blender/blenlib/intern/math_time.c @@ -23,13 +23,6 @@ #include "BLI_math.h" -/** Explode given time value expressed in seconds, into a set of days, hours, minutes, seconds - * and/or milliseconds (depending on which return parameters are not NULL). - * - * \note The smallest given return parameter will get the potential fractional remaining time - * value. E.g. if you give `seconds=90.0` and do not pass `r_seconds` and `r_milliseconds`, - * `r_minutes` will be set to `1.5`. - */ void BLI_math_time_seconds_decompose(double seconds, double *r_days, double *r_hours, diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 35dfe421cf0..a0afab8a179 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -37,8 +37,6 @@ void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float r[1] = s * a[1] + t * b[1]; } -/* weight 3 2D vectors, - * 'w' must be unit length but is not a vector, just 3 weights */ void interp_v2_v2v2v2( float r[2], const float a[2], const float b[2], const float c[2], const float t[3]) { @@ -65,12 +63,6 @@ void interp_v4_v4v4(float r[4], const float a[4], const float b[4], const float r[3] = s * a[3] + t * b[3]; } -/** - * slerp, treat vectors as spherical coordinates - * \see #interp_qt_qtqt - * - * \return success - */ bool interp_v3_v3v3_slerp(float target[3], const float a[3], const float b[3], const float t) { float cosom, w[2]; @@ -115,9 +107,6 @@ bool interp_v2_v2v2_slerp(float target[2], const float a[2], const float b[2], c return true; } -/** - * Same as #interp_v3_v3v3_slerp but uses fallback values for opposite vectors. - */ void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], const float t) { if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, b, t))) { @@ -186,8 +175,6 @@ void interp_v2_v2v2v2v2_cubic(float p[2], /** \} */ -/* weight 3 vectors, - * 'w' must be unit length but is not a vector, just 3 weights */ void interp_v3_v3v3v3( float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]) { @@ -196,8 +183,6 @@ void interp_v3_v3v3v3( p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2]; } -/* weight 3 vectors, - * 'w' must be unit length but is not a vector, just 4 weights */ void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], @@ -311,18 +296,6 @@ void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const uint nbr) } } -/** - * Specialized function for calculating normals. - * Fast-path for: - * - * \code{.c} - * add_v3_v3v3(r, a, b); - * normalize_v3(r) - * mul_v3_fl(r, angle_normalized_v3v3(a, b) / M_PI_2); - * \endcode - * - * We can use the length of (a + b) to calculate the angle. - */ void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3]) { /* trick, we want the middle of 2 normals as well as the angle between them @@ -341,10 +314,6 @@ void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3]) acosf(normalize_v3(r) / 2.0f); mul_v3_fl(r, angle); } -/** - * Same as mid_v3_v3v3_angle_weighted - * but \a r is assumed to be accumulated normals, divided by their total. - */ void mid_v3_angle_weighted(float r[3]) { /* trick, we want the middle of 2 normals as well as the angle between them @@ -407,13 +376,6 @@ bool is_finite_v4(const float v[4]) /********************************** Angles ***********************************/ -/* Return the angle in radians between vecs 1-2 and 2-3 in radians - * If v1 is a shoulder, v2 is the elbow and v3 is the hand, - * this would return the angle at the elbow. - * - * note that when v1/v2/v3 represent 3 points along a straight line - * that the angle returned will be pi (180deg), rather than 0.0 - */ float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) { float vec1[3], vec2[3]; @@ -426,7 +388,6 @@ float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) return angle_normalized_v3v3(vec1, vec2); } -/* Quicker than full angle computation */ float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) { float vec1[3], vec2[3]; @@ -439,7 +400,6 @@ float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) return dot_v3v3(vec1, vec2); } -/* Return the shortest angle in radians between the 2 vectors */ float angle_v3v3(const float a[3], const float b[3]) { float vec1[3], vec2[3]; @@ -466,7 +426,6 @@ float angle_v2v2v2(const float a[2], const float b[2], const float c[2]) return angle_normalized_v2v2(vec1, vec2); } -/* Quicker than full angle computation */ float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2]) { float vec1[2], vec2[2]; @@ -479,7 +438,6 @@ float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2]) return dot_v2v2(vec1, vec2); } -/* Return the shortest angle in radians between the 2 vectors */ float angle_v2v2(const float a[2], const float b[2]) { float vec1[2], vec2[2]; @@ -534,9 +492,6 @@ float angle_normalized_v2v2(const float a[2], const float b[2]) return (float)M_PI - 2.0f * saasin(len_v2v2(a, v2_n) / 2.0f); } -/** - * Angle between 2 vectors, about an axis (axis can be considered a plane). - */ float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) { float v1_proj[3], v2_proj[3]; @@ -568,9 +523,6 @@ float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const f return angle; } -/** - * Angle between 2 vectors defined by 3 coords, about an axis (axis can be considered a plane). - */ float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], @@ -652,9 +604,6 @@ void angle_poly_v3(float *angles, const float *verts[3], int len) /********************************* Geometry **********************************/ -/** - * Project \a p onto \a v_proj - */ void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2]) { if (UNLIKELY(is_zero_v2(v_proj))) { @@ -666,9 +615,6 @@ void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2]) mul_v2_v2fl(out, v_proj, mul); } -/** - * Project \a p onto \a v_proj - */ void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3]) { if (UNLIKELY(is_zero_v3(v_proj))) { @@ -691,9 +637,6 @@ void project_v3_v3v3_db(double out[3], const double p[3], const double v_proj[3] mul_v3_v3db_db(out, v_proj, mul); } -/** - * Project \a p onto a unit length \a v_proj - */ void project_v2_v2v2_normalized(float out[2], const float p[2], const float v_proj[2]) { BLI_ASSERT_UNIT_V2(v_proj); @@ -702,9 +645,6 @@ void project_v2_v2v2_normalized(float out[2], const float p[2], const float v_pr mul_v2_v2fl(out, v_proj, mul); } -/** - * Project \a p onto a unit length \a v_proj - */ void project_v3_v3v3_normalized(float out[3], const float p[3], const float v_proj[3]) { BLI_ASSERT_UNIT_V3(v_proj); @@ -713,19 +653,6 @@ void project_v3_v3v3_normalized(float out[3], const float p[3], const float v_pr mul_v3_v3fl(out, v_proj, mul); } -/** - * In this case plane is a 3D vector only (no 4th component). - * - * Projecting will make \a out a copy of \a p orthogonal to \a v_plane. - * - * \note If \a p is exactly perpendicular to \a v_plane, \a out will just be a copy of \a p. - * - * \note This function is a convenience to call: - * \code{.c} - * project_v3_v3v3(out, p, v_plane); - * sub_v3_v3v3(out, p, out); - * \endcode - */ void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3]) { const float mul = dot_v3v3(p, v_plane) / dot_v3v3(v_plane, v_plane); @@ -756,7 +683,6 @@ void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const floa madd_v2_v2v2fl(out, p, v_plane, -mul); } -/* project a vector on a plane defined by normal and a plane point p */ void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3]) { float vector[3]; @@ -769,7 +695,6 @@ void project_v3_plane(float out[3], const float plane_no[3], const float plane_c madd_v3_v3fl(out, plane_no, -mul); } -/* Returns a vector bisecting the angle at b formed by a, b and c */ void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]) { float d_12[3], d_23[3]; @@ -781,22 +706,6 @@ void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const floa normalize_v3(r); } -/** - * Returns a reflection vector from a vector and a normal vector - * reflect = vec - ((2 * dot(vec, mirror)) * mirror). - * - * <pre> - * v - * + ^ - * \ | - * \| - * + normal: axis of reflection - * / - * / - * + - * out: result (negate for a 'bounce'). - * </pre> - */ void reflect_v3_v3v3(float out[3], const float v[3], const float normal[3]) { BLI_ASSERT_UNIT_V3(normal); @@ -813,11 +722,6 @@ void reflect_v3_v3v3_db(double out[3], const double v[3], const double normal[3] madd_v3_v3v3db_db(out, v, normal, -dot2); } -/** - * Takes a vector and computes 2 orthogonal directions. - * - * \note if \a n is n unit length, computed values will be too. - */ void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]) { const float eps = FLT_EPSILON; @@ -843,11 +747,6 @@ void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]) } } -/** - * Calculates \a p - a perpendicular vector to \a v - * - * \note return vector won't maintain same length. - */ void ortho_v3_v3(float out[3], const float v[3]) { const int axis = axis_dominant_v3_single(v); @@ -873,9 +772,6 @@ void ortho_v3_v3(float out[3], const float v[3]) } } -/** - * no brainer compared to v3, just have for consistency. - */ void ortho_v2_v2(float out[2], const float v[2]) { BLI_assert(out != v); @@ -884,9 +780,6 @@ void ortho_v2_v2(float out[2], const float v[2]) out[1] = v[0]; } -/** - * Rotate a point \a p by \a angle around origin (0, 0) - */ void rotate_v2_v2fl(float r[2], const float p[2], const float angle) { const float co = cosf(angle); @@ -898,10 +791,6 @@ void rotate_v2_v2fl(float r[2], const float p[2], const float angle) r[1] = si * p[0] + co * p[1]; } -/** - * Rotate a point \a p by \a angle around an arbitrary unit length \a axis. - * http://local.wasp.uwa.edu.au/~pbourke/geometry/ - */ void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axis[3], @@ -1040,7 +929,6 @@ void minmax_v3v3_v3_array(float r_min[3], float r_max[3], const float (*vec_arr) } } -/** ensure \a v1 is \a dist from \a v2 */ void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist) { if (!equals_v3v3(v2, v1)) { diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index bb32b511005..648f876acaa 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -101,6 +101,7 @@ MINLINE void copy_v4_fl(float r[4], float f) } /* unsigned char */ + MINLINE void copy_v2_v2_uchar(unsigned char r[2], const unsigned char a[2]) { r[0] = a[0]; @@ -144,6 +145,7 @@ MINLINE void copy_v4_uchar(unsigned char r[4], const unsigned char a) } /* char */ + MINLINE void copy_v2_v2_char(char r[2], const char a[2]) { r[0] = a[0]; @@ -224,6 +226,7 @@ MINLINE void copy_v4_v4_int(int r[4], const int a[4]) } /* double */ + MINLINE void zero_v3_db(double r[3]) { r[0] = 0.0; @@ -252,7 +255,6 @@ MINLINE void copy_v4_v4_db(double r[4], const double a[4]) r[3] = a[3]; } -/* int <-> float */ MINLINE void round_v2i_v2fl(int r[2], const float a[2]) { r[0] = (int)roundf(a[0]); @@ -266,6 +268,7 @@ MINLINE void copy_v2fl_v2i(float r[2], const int a[2]) } /* double -> float */ + MINLINE void copy_v2fl_v2db(float r[2], const double a[2]) { r[0] = (float)a[0]; @@ -288,6 +291,7 @@ MINLINE void copy_v4fl_v4db(float r[4], const double a[4]) } /* float -> double */ + MINLINE void copy_v2db_v2fl(double r[2], const float a[2]) { r[0] = (double)a[0]; @@ -331,6 +335,7 @@ MINLINE void swap_v4_v4(float a[4], float b[4]) } /* float args -> vec */ + MINLINE void copy_v2_fl2(float v[2], float x, float y) { v[0] = x; @@ -639,26 +644,11 @@ MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2]) r[1] = mat[1] * vec[0] + (+mat[0]) * vec[1]; } -/** - * Convenience function to get the projected depth of a position. - * This avoids creating a temporary 4D vector and multiplying it - only for the 4th component. - * - * Matches logic for: - * - * \code{.c} - * float co_4d[4] = {co[0], co[1], co[2], 1.0}; - * mul_m4_v4(mat, co_4d); - * return co_4d[3]; - * \endcode - */ MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3]) { return (mat[0][3] * co[0]) + (mat[1][3] * co[1]) + (mat[2][3] * co[2]) + mat[3][3]; } -/** - * Has the effect of #mul_m3_v3(), on a single axis. - */ MINLINE float dot_m3_v3_row_x(const float M[3][3], const float a[3]) { return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2]; @@ -672,10 +662,6 @@ MINLINE float dot_m3_v3_row_z(const float M[3][3], const float a[3]) return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2]; } -/** - * Has the effect of #mul_mat3_m4_v3(), on a single axis. - * (no adding translation) - */ MINLINE float dot_m4_v3_row_x(const float M[4][4], const float a[3]) { return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2]; @@ -817,7 +803,6 @@ MINLINE void negate_v4_v4(float r[4], const float a[4]) r[3] = -a[3]; } -/* could add more... */ MINLINE void negate_v3_short(short r[3]) { r[0] = (short)-r[0]; @@ -962,8 +947,6 @@ MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]) r[2] = a[0] * b[1] - a[1] * b[0]; } -/* cross product suffers from severe precision loss when vectors are - * nearly parallel or opposite; doing the computation in double helps a lot */ MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3]) { BLI_assert(r != a && r != b); @@ -980,10 +963,6 @@ MINLINE void cross_v3_v3v3_db(double r[3], const double a[3], const double b[3]) r[2] = a[0] * b[1] - a[1] * b[0]; } -/* Newell's Method */ -/* excuse this fairly specific function, - * its used for polygon normals all over the place - * could use a better name */ MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]) { n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]); @@ -1158,9 +1137,6 @@ MINLINE float len_v4v4(const float a[4], const float b[4]) return len_v4(d); } -/** - * \note any vectors containing `nan` will be zeroed out. - */ MINLINE float normalize_v2_v2_length(float r[2], const float a[2], const float unit_length) { float d = dot_v2v2(a, a); @@ -1192,9 +1168,6 @@ MINLINE float normalize_v2_length(float n[2], const float unit_length) return normalize_v2_v2_length(n, n, unit_length); } -/** - * \note any vectors containing `nan` will be zeroed out. - */ MINLINE float normalize_v3_v3_length(float r[3], const float a[3], const float unit_length) { float d = dot_v3v3(a, a); @@ -1498,18 +1471,6 @@ MINLINE void clamp_v4_v4v4(float vec[4], const float min[4], const float max[4]) /** \} */ -/** - * <pre> - * + l1 - * | - * neg <- | -> pos - * | - * + l2 - * </pre> - * - * \return Positive value when 'pt' is left-of-line - * (looking from 'l1' -> 'l2'). - */ MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]) { return (((l1[0] - pt[0]) * (l2[1] - pt[1])) - ((l2[0] - pt[0]) * (l1[1] - pt[1]))); diff --git a/source/blender/blenlib/intern/memory_utils.c b/source/blender/blenlib/intern/memory_utils.c index 4bb93877401..2befcb1bb19 100644 --- a/source/blender/blenlib/intern/memory_utils.c +++ b/source/blender/blenlib/intern/memory_utils.c @@ -30,9 +30,6 @@ #include "BLI_strict_flags.h" -/** - * Check if memory is zeroed, as with `memset(arr, 0, arr_size)`. - */ bool BLI_memory_is_zero(const void *arr, const size_t arr_size) { const char *arr_byte = arr; diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc index 20b696bb56f..ce4db0c6b9d 100644 --- a/source/blender/blenlib/intern/mesh_boolean.cc +++ b/source/blender/blenlib/intern/mesh_boolean.cc @@ -3676,10 +3676,6 @@ static void dump_test_spec(IMesh &imesh) } } -/** - * Do the boolean operation op on the polygon mesh imesh_in. - * See the header file for a complete description. - */ IMesh boolean_mesh(IMesh &imesh, BoolOpType op, int nshapes, diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc index 1af4dfb029d..ab1db3f1fda 100644 --- a/source/blender/blenlib/intern/mesh_intersect.cc +++ b/source/blender/blenlib/intern/mesh_intersect.cc @@ -150,7 +150,6 @@ Plane::Plane(const double3 &norm, const double d) : norm(norm), d(d) norm_exact = mpq3(0, 0, 0); /* Marks as "exact not yet populated". */ } -/** This is wrong for degenerate planes, but we don't expect to call it on those. */ bool Plane::exact_populated() const { return norm_exact[0] != 0 || norm_exact[1] != 0 || norm_exact[2] != 0; @@ -803,11 +802,6 @@ std::ostream &operator<<(std::ostream &os, const IMesh &mesh) return os; } -/** - * Assume bounding boxes have been expanded by a sufficient epsilon on all sides - * so that the comparisons against the bb bounds are sufficient to guarantee that - * if an overlap or even touching could happen, this will return true. - */ bool bbs_might_intersect(const BoundingBox &bb_a, const BoundingBox &bb_b) { return isect_aabb_aabb_v3(bb_a.min, bb_a.max, bb_b.min, bb_b.max); @@ -2276,12 +2270,6 @@ static Array<Face *> triangulate_poly(Face *f, IMeshArena *arena) return ans; } -/** - * Return an #IMesh that is a triangulation of a mesh with general - * polygonal faces, #IMesh. - * Added diagonals will be distinguishable by having edge original - * indices of #NO_INDEX. - */ IMesh triangulate_polymesh(IMesh &imesh, IMeshArena *arena) { Vector<Face *> face_tris; @@ -2962,7 +2950,6 @@ static IMesh remove_degenerate_tris(const IMesh &tm_in) return ans; } -/* This is the main routine for calculating the self_intersection of a triangle mesh. */ IMesh trimesh_self_intersect(const IMesh &tm_in, IMeshArena *arena) { return trimesh_nary_intersect( @@ -3137,9 +3124,6 @@ static std::ostream &operator<<(std::ostream &os, const ITT_value &itt) return os; } -/** - * Writing the obj_mesh has the side effect of populating verts. - */ void write_obj_mesh(IMesh &m, const std::string &objname) { /* Would like to use #BKE_tempdir_base() here, but that brings in dependence on kernel library. diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index a0938f4f713..ce4dee16d32 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -429,15 +429,17 @@ static float orgBlenderNoise(float x, float y, float z) return n; } -/* as orgBlenderNoise(), returning signed noise */ static float orgBlenderNoiseS(float x, float y, float z) { + /* NOTE: As #orgBlenderNoise(), returning signed noise. */ + return (2.0f * orgBlenderNoise(x, y, z) - 1.0f); } -/* separated from orgBlenderNoise above, with scaling */ float BLI_noise_hnoise(float noisesize, float x, float y, float z) { + /* NOTE: Separated from orgBlenderNoise, with scaling. */ + if (noisesize == 0.0f) { return 0.0f; } @@ -447,7 +449,6 @@ float BLI_noise_hnoise(float noisesize, float x, float y, float z) return orgBlenderNoise(x, y, z); } -/* original turbulence functions */ float BLI_noise_turbulence(float noisesize, float x, float y, float z, int nr) { float s, d = 0.5, div = 1.0; @@ -926,8 +927,6 @@ static float dist_Minkovsky(float x, float y, float z, float e) return powf(powf(fabsf(x), e) + powf(fabsf(y), e) + powf(fabsf(z), e), 1.0f / e); } -/* Not 'pure' Worley, but the results are virtually the same. - * Returns distances in da and point coords in pa */ void BLI_noise_voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype) { float (*distfunc)(float, float, float, float); @@ -1137,13 +1136,11 @@ static float BLI_cellNoiseU(float x, float y, float z) return ((float)(n * (n * n * 15731 + 789221) + 1376312589) / 4294967296.0f); } -/* idem, signed */ float BLI_noise_cell(float x, float y, float z) { return (2.0f * BLI_cellNoiseU(x, y, z) - 1.0f); } -/* returns a vector/point/color in ca, using point hasharray directly */ void BLI_noise_cell_v3(float x, float y, float z, float ca[3]) { /* avoid precision issues on unit coordinates */ @@ -1166,9 +1163,6 @@ void BLI_noise_cell_v3(float x, float y, float z, float ca[3]) /** \name Public API's * \{ */ -/** - * newnoise: generic noise function for use with different `noisebasis`. - */ float BLI_noise_generic_noise( float noisesize, float x, float y, float z, bool hard, int noisebasis) { @@ -1226,7 +1220,6 @@ float BLI_noise_generic_noise( return noisefunc(x, y, z); } -/* newnoise: generic turbulence function for use with different noisebasis */ float BLI_noise_generic_turbulence( float noisesize, float x, float y, float z, int oct, bool hard, int noisebasis) { @@ -1289,21 +1282,12 @@ float BLI_noise_generic_turbulence( return sum; } -/* - * The following code is based on Ken Musgrave's explanations and sample - * source code in the book "Texturing and Modeling: A procedural approach" - */ - -/** - * Procedural `fBm` evaluated at "point"; returns value stored in "value". - * - * \param H: is the fractal increment parameter. - * \param lacunarity: is the gap between successive frequencies. - * \param octaves: is the number of frequencies in the `fBm`. - */ float BLI_noise_mg_fbm( float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis) { + /* The following code is based on Ken Musgrave's explanations and sample + * source code in the book "Texturing and Modeling: A procedural approach". */ + float (*noisefunc)(float, float, float); switch (noisebasis) { case 1: @@ -1358,24 +1342,13 @@ float BLI_noise_mg_fbm( } /* fBm() */ -/** - * Procedural multi-fractal evaluated at "point"; - * returns value stored in "value". - * - * \param H: determines the highest fractal dimension. - * \param lacunarity: is gap between successive frequencies. - * \param octaves: is the number of frequencies in the `fBm`. - * - * \note There used to be a parameter called `offset`, old docs read: - * is the zero offset, which determines multi-fractality. - */ - -/* this one is in fact rather confusing, - * there seem to be errors in the original source code (in all three versions of proc.text&mod), - * I modified it to something that made sense to me, so it might be wrong... */ float BLI_noise_mg_multi_fractal( float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis) { + /* This one is in fact rather confusing, + * there seem to be errors in the original source code (in all three versions of proc.text&mod), + * I modified it to something that made sense to me, so it might be wrong. */ + float (*noisefunc)(float, float, float); switch (noisebasis) { case 1: @@ -1428,15 +1401,6 @@ float BLI_noise_mg_multi_fractal( return value; } -/** - * Heterogeneous procedural terrain function: stats by altitude method. - * Evaluated at "point"; returns value stored in "value". - * - * \param H: Determines the fractal dimension of the roughest areas. - * \param lacunarity: Is the gap between successive frequencies. - * \param octaves: Is the number of frequencies in the `fBm`. - * \param offset: Raises the terrain from `sea level`. - */ float BLI_noise_mg_hetero_terrain(float x, float y, float z, @@ -1507,13 +1471,6 @@ float BLI_noise_mg_hetero_terrain(float x, return value; } -/* Hybrid additive/multiplicative multifractal terrain model. - * - * Some good parameter values to start with: - * - * H: 0.25 - * offset: 0.7 - */ float BLI_noise_mg_hybrid_multi_fractal(float x, float y, float z, @@ -1590,14 +1547,6 @@ float BLI_noise_mg_hybrid_multi_fractal(float x, } /* HybridMultifractal() */ -/* Ridged multifractal terrain model. - * - * Some good parameter values to start with: - * - * H: 1.0 - * offset: 1.0 - * gain: 2.0 - */ float BLI_noise_mg_ridged_multi_fractal(float x, float y, float z, @@ -1669,9 +1618,6 @@ float BLI_noise_mg_ridged_multi_fractal(float x, return result; } /* RidgedMultifractal() */ -/* "Variable Lacunarity Noise" - * A distorted variety of Perlin noise. - */ float BLI_noise_mg_variable_lacunarity( float x, float y, float z, float distortion, int nbas1, int nbas2) { diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 182fe211110..c40eed711f5 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -69,17 +69,6 @@ static bool BLI_path_is_abs(const char *name); /* implementation */ -/** - * Looks for a sequence of decimal digits in string, preceding any filename extension, - * returning the integer value if found, or 0 if not. - * - * \param string: String to scan. - * \param head: Optional area to return copy of part of string prior to digits, - * or before dot if no digits. - * \param tail: Optional area to return copy of part of string following digits, - * or from dot if no digits. - * \param r_num_len: Optional to return number of digits found. - */ int BLI_path_sequence_decode(const char *string, char *head, char *tail, ushort *r_num_len) { uint nums = 0, nume = 0; @@ -147,10 +136,6 @@ int BLI_path_sequence_decode(const char *string, char *head, char *tail, ushort return 0; } -/** - * Returns in area pointed to by string a string of the form "<head><pic><tail>", where pic - * is formatted as numlen digits with leading zeroes. - */ void BLI_path_sequence_encode( char *string, const char *head, const char *tail, unsigned short numlen, int pic) { @@ -161,15 +146,6 @@ static int BLI_path_unc_prefix_len(const char *path); /* defined below in same f /* ******************** string encoding ***************** */ -/** - * Remove redundant characters from \a path and optionally make absolute. - * - * \param relabase: The path this is relative to, or ignored when NULL. - * \param path: Can be any input, and this function converts it to a regular full path. - * Also removes garbage from directory paths, like `/../` or double slashes etc. - * - * \note \a path isn't protected for max string names... - */ void BLI_path_normalize(const char *relabase, char *path) { ptrdiff_t a; @@ -260,9 +236,6 @@ void BLI_path_normalize(const char *relabase, char *path) #endif } -/** - * Cleanup filepath ensuring a trailing slash. - */ void BLI_path_normalize_dir(const char *relabase, char *dir) { /* Would just create an unexpected "/" path, just early exit entirely. */ @@ -274,28 +247,6 @@ void BLI_path_normalize_dir(const char *relabase, char *dir) BLI_path_slash_ensure(dir); } -/** - * Make given name safe to be used in paths. - * - * \return true if \a fname was changed, false otherwise. - * - * For now, simply replaces reserved chars (as listed in - * https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words ) - * by underscores ('_'). - * - * \note Space case ' ' is a bit of an edge case here - in theory it is allowed, - * but again can be an issue in some cases, so we simply replace it by an underscore too - * (good practice anyway). - * REMOVED based on popular demand (see T45900). - * Percent '%' char is a bit same case - not recommended to use it, - * but supported by all decent file-systems/operating-systems around. - * - * \note On Windows, it also ensures there is no '.' (dot char) at the end of the file, - * this can lead to issues. - * - * \note On Windows, it also checks for forbidden names - * (see https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx ). - */ bool BLI_filename_make_safe(char *fname) { const char *invalid = @@ -366,11 +317,6 @@ bool BLI_filename_make_safe(char *fname) return changed; } -/** - * Make given path OS-safe. - * - * \return true if \a path was changed, false otherwise. - */ bool BLI_path_make_safe(char *path) { /* Simply apply BLI_filename_make_safe() over each component of the path. @@ -404,16 +350,11 @@ bool BLI_path_make_safe(char *path) return changed; } -/** - * Does path begin with the special "//" prefix that Blender uses to indicate - * a path relative to the .blend file. - */ bool BLI_path_is_rel(const char *path) { return path[0] == '/' && path[1] == '/'; } -/* return true if the path is a UNC share */ bool BLI_path_is_unc(const char *name) { return name[0] == '\\' && name[1] == '\\'; @@ -512,10 +453,6 @@ void BLI_path_normalize_unc_16(wchar_t *path_16) } #endif -/** - * Replaces `file` with a relative version (prefixed by "//") such that #BLI_path_abs, given - * the same `relfile`, will convert it back to its original value. - */ void BLI_path_rel(char *file, const char *relfile) { const char *lslash; @@ -654,18 +591,6 @@ void BLI_path_rel(char *file, const char *relfile) } } -/** - * Appends a suffix to the string, fitting it before the extension - * - * string = Foo.png, suffix = 123, separator = _ - * Foo.png -> Foo_123.png - * - * \param string: original (and final) string - * \param maxlen: Maximum length of string - * \param suffix: String to append to the original string - * \param sep: Optional separator character - * \return true if succeeded - */ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char *sep) { #ifdef DEBUG_STRSIZE @@ -701,10 +626,6 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char return true; } -/** - * Replaces path with the path of its parent directory, returning true if - * it was able to find a parent directory within the path. - */ bool BLI_path_parent_dir(char *path) { const char parent_dir[] = {'.', '.', SEP, '\0'}; /* "../" or "..\\" */ @@ -721,10 +642,6 @@ bool BLI_path_parent_dir(char *path) return false; } -/** - * Strips off nonexistent (or non-accessible) sub-directories from the end of `dir`, - * leaving the path of the lowest-level directory that does exist and we can read. - */ bool BLI_path_parent_dir_until_exists(char *dir) { bool valid_path = true; @@ -795,10 +712,6 @@ static void ensure_digits(char *path, int digits) } } -/** - * Replaces "#" character sequence in last slash-separated component of `path` - * with frame as decimal integer, with leading zeroes as necessary, to make digits digits. - */ bool BLI_path_frame(char *path, int frame, int digits) { int ch_sta, ch_end; @@ -817,11 +730,6 @@ bool BLI_path_frame(char *path, int frame, int digits) return false; } -/** - * Replaces "#" character sequence in last slash-separated component of `path` - * with sta and end as decimal integers, with leading zeroes as necessary, to make digits - * digits each, with a hyphen in-between. - */ bool BLI_path_frame_range(char *path, int sta, int end, int digits) { int ch_sta, ch_end; @@ -848,9 +756,6 @@ bool BLI_path_frame_range(char *path, int sta, int end, int digits) return false; } -/** - * Get the frame from a filename formatted by blender's frame scheme - */ bool BLI_path_frame_get(char *path, int *r_frame, int *r_numdigits) { if (*path) { @@ -952,19 +857,12 @@ void BLI_path_frame_strip(char *path, char *r_ext) *c = '\0'; } -/** - * Check if we have '#' chars, usable for #BLI_path_frame, #BLI_path_frame_range - */ bool BLI_path_frame_check_chars(const char *path) { int ch_sta, ch_end; /* dummy args */ return stringframe_chars(path, &ch_sta, &ch_end); } -/** - * Creates a display string from path to be used menus and the user interface. - * Like `bpy.path.display_name()`. - */ void BLI_path_to_display_name(char *display_name, int maxlen, const char *name) { /* Strip leading underscores and spaces. */ @@ -1003,16 +901,6 @@ void BLI_path_to_display_name(char *display_name, int maxlen, const char *name) } } -/** - * If path begins with "//", strips that and replaces it with `basepath` directory. - * - * \note Also converts drive-letter prefix to something more sensible - * if this is a non-drive-letter-based system. - * - * \param path: The path to convert. - * \param basepath: The directory to base relative paths with. - * \return true if the path was relative (started with "//"). - */ bool BLI_path_abs(char *path, const char *basepath) { const bool wasrelative = BLI_path_is_rel(path); @@ -1114,14 +1002,6 @@ bool BLI_path_abs(char *path, const char *basepath) return wasrelative; } -/** - * Checks for relative path, expanding them relative to the current working directory. - * Returns true if the expansion was performed. - * - * \note Should only be called with command line paths. - * This is _not_ something Blender's internal paths support, instead they use the "//" prefix. - * In most cases #BLI_path_abs should be used instead. - */ bool BLI_path_abs_from_cwd(char *path, const size_t maxlen) { #ifdef DEBUG_STRSIZE @@ -1209,9 +1089,6 @@ bool BLI_path_program_extensions_add_win32(char *name, const size_t maxlen) } #endif /* WIN32 */ -/** - * Search for a binary (executable) - */ bool BLI_path_program_search(char *fullname, const size_t maxlen, const char *name) { #ifdef DEBUG_STRSIZE @@ -1264,10 +1141,6 @@ bool BLI_path_program_search(char *fullname, const size_t maxlen, const char *na return retval; } -/** - * Sets the specified environment variable to the specified value, - * and clears it if `val == NULL`. - */ void BLI_setenv(const char *env, const char *val) { /* free windows */ @@ -1286,12 +1159,6 @@ void BLI_setenv(const char *env, const char *val) #endif } -/** - * Only set an env var if already not there. - * Like Unix setenv(env, val, 0); - * - * (not used anywhere). - */ void BLI_setenv_if_new(const char *env, const char *val) { if (BLI_getenv(env) == NULL) { @@ -1299,14 +1166,6 @@ void BLI_setenv_if_new(const char *env, const char *val) } } -/** - * Get an env var, result has to be used immediately. - * - * On windows #getenv gets its variables from a static copy of the environment variables taken at - * process start-up, causing it to not pick up on environment variables created during runtime. - * This function uses an alternative method to get environment variables that does pick up on - * runtime environment variables. The result will be UTF-8 encoded. - */ const char *BLI_getenv(const char *env) { #ifdef _MSC_VER @@ -1336,11 +1195,6 @@ const char *BLI_getenv(const char *env) #endif } -/** - * Ensures that the parent directory of `name` exists. - * - * \return true on success (i.e. given path now exists on file-system), false otherwise. - */ bool BLI_make_existing_file(const char *name) { char di[FILE_MAX]; @@ -1350,15 +1204,6 @@ bool BLI_make_existing_file(const char *name) return BLI_dir_create_recursive(di); } -/** - * Returns in `string` the concatenation of `dir` and `file` (also with `relabase` on the - * front if specified and `dir` begins with "//"). Normalizes all occurrences of path - * separators, including ensuring there is exactly one between the copies of `dir` and `file`, - * and between the copies of `relabase` and `dir`. - * - * \param relabase: Optional prefix to substitute for "//" on front of `dir`. - * \param string: Area to return result. - */ void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file) { int sl; @@ -1452,7 +1297,6 @@ static bool path_extension_check_ex(const char *str, (BLI_strcasecmp(ext, str + str_len - ext_len) == 0)); } -/* does str end with ext. */ bool BLI_path_extension_check(const char *str, const char *ext) { return path_extension_check_ex(str, strlen(str), ext, strlen(ext)); @@ -1480,7 +1324,6 @@ bool BLI_path_extension_check_n(const char *str, ...) return ret; } -/* does str end with any of the suffixes in *ext_array. */ bool BLI_path_extension_check_array(const char *str, const char **ext_array) { const size_t str_len = strlen(str); @@ -1496,10 +1339,6 @@ bool BLI_path_extension_check_array(const char *str, const char **ext_array) return false; } -/** - * Semicolon separated wildcards, eg: `*.zip;*.py;*.exe` - * does str match any of the semicolon-separated glob patterns in #fnmatch. - */ bool BLI_path_extension_check_glob(const char *str, const char *ext_fnmatch) { const char *ext_step = ext_fnmatch; @@ -1526,15 +1365,6 @@ bool BLI_path_extension_check_glob(const char *str, const char *ext_fnmatch) return false; } -/** - * Does basic validation of the given glob string, to prevent common issues from string - * truncation. - * - * For now, only forbids last group to be a wildcard-only one, if there are more than one group - * (i.e. things like `*.txt;*.cpp;*` are changed to `*.txt;*.cpp;`) - * - * \returns true if it had to modify given \a ext_fnmatch pattern. - */ bool BLI_path_extension_glob_validate(char *ext_fnmatch) { bool only_wildcards = false; @@ -1561,10 +1391,6 @@ bool BLI_path_extension_glob_validate(char *ext_fnmatch) return false; } -/** - * Removes any existing extension on the end of \a path and appends \a ext. - * \return false if there was no room. - */ bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) { #ifdef DEBUG_STRSIZE @@ -1592,9 +1418,6 @@ bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) return true; } -/** - * Strip's trailing '.'s and adds the extension only when needed - */ bool BLI_path_extension_ensure(char *path, size_t maxlen, const char *ext) { #ifdef DEBUG_STRSIZE @@ -1640,14 +1463,6 @@ bool BLI_path_filename_ensure(char *filepath, size_t maxlen, const char *filenam return false; } -/** - * Converts `/foo/bar.txt` to `/foo/` and `bar.txt` - * - * - Won't change \a string. - * - Won't create any directories. - * - Doesn't use CWD, or deal with relative paths. - * - Only fill's in \a dir and \a file when they are non NULL. - */ void BLI_split_dirfile( const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen) { @@ -1673,26 +1488,16 @@ void BLI_split_dirfile( } } -/** - * Copies the parent directory part of string into `dir`, max length `dirlen`. - */ void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen) { BLI_split_dirfile(string, dir, NULL, dirlen, 0); } -/** - * Copies the leaf filename part of string into `file`, max length `filelen`. - */ void BLI_split_file_part(const char *string, char *file, const size_t filelen) { BLI_split_dirfile(string, NULL, file, 0, filelen); } -/** - * Returns a pointer to the last extension (e.g. the position of the last period). - * Returns NULL if there is no extension. - */ const char *BLI_path_extension(const char *filepath) { const char *extension = strrchr(filepath, '.'); @@ -1707,9 +1512,6 @@ const char *BLI_path_extension(const char *filepath) return extension; } -/** - * Append a filename to a dir, ensuring slash separates. - */ void BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__restrict file) { size_t dirlen = BLI_strnlen(dst, maxlen); @@ -1727,13 +1529,6 @@ void BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__re BLI_strncpy(dst + dirlen, file, maxlen - dirlen); } -/** - * Simple appending of filename to dir, does not check for valid path! - * Puts result into `dst`, which may be same area as `dir`. - * - * \note Consider using #BLI_path_join for more general path joining - * that de-duplicates separators and can handle an arbitrary number of paths. - */ void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, @@ -1776,13 +1571,6 @@ void BLI_join_dirfile(char *__restrict dst, BLI_strncpy(dst + dirlen, file, maxlen - dirlen); } -/** - * Join multiple strings into a path, ensuring only a single path separator between each, - * and trailing slash is kept. - * - * \note If you want a trailing slash, add `SEP_STR` as the last path argument, - * duplicate slashes will be cleaned up. - */ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *path, ...) { #ifdef DEBUG_STRSIZE @@ -1863,27 +1651,12 @@ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *pat return ofs; } -/** - * like Python's `os.path.basename()` - * - * \return The pointer into \a path string immediately after last slash, - * or start of \a path if none found. - */ const char *BLI_path_basename(const char *path) { const char *const filename = BLI_path_slash_rfind(path); return filename ? filename + 1 : path; } -/** - * Get an element of the path at an index, eg: - * "/some/path/file.txt" where an index of... - * - 0 or -3: "some" - * - 1 or -2: "path" - * - 2 or -1: "file.txt" - * - * Ignores multiple slashes at any point in the path (including start/end). - */ bool BLI_path_name_at_index(const char *__restrict path, const int index, int *__restrict r_offset, @@ -1975,9 +1748,6 @@ bool BLI_path_contains(const char *container_path, const char *containee_path) return BLI_str_startswith(containee_native, container_native); } -/** - * Returns pointer to the leftmost path separator in string. Not actually used anywhere. - */ const char *BLI_path_slash_find(const char *string) { const char *const ffslash = strchr(string, '/'); @@ -1993,9 +1763,6 @@ const char *BLI_path_slash_find(const char *string) return (ffslash < fbslash) ? ffslash : fbslash; } -/** - * Returns pointer to the rightmost path separator in string. - */ const char *BLI_path_slash_rfind(const char *string) { const char *const lfslash = strrchr(string, '/'); @@ -2011,10 +1778,6 @@ const char *BLI_path_slash_rfind(const char *string) return (lfslash > lbslash) ? lfslash : lbslash; } -/** - * Appends a slash to string if there isn't one there already. - * Returns the new length of the string. - */ int BLI_path_slash_ensure(char *string) { int len = strlen(string); @@ -2026,9 +1789,6 @@ int BLI_path_slash_ensure(char *string) return len; } -/** - * Removes the last slash and everything after it to the end of string, if there is one. - */ void BLI_path_slash_rstrip(char *string) { int len = strlen(string); @@ -2043,9 +1803,6 @@ void BLI_path_slash_rstrip(char *string) } } -/** - * Changes to the path separators to the native ones for this OS. - */ void BLI_path_slash_native(char *path) { #ifdef WIN32 diff --git a/source/blender/blenlib/intern/polyfill_2d.c b/source/blender/blenlib/intern/polyfill_2d.c index 9af98359199..2a02abf147a 100644 --- a/source/blender/blenlib/intern/polyfill_2d.c +++ b/source/blender/blenlib/intern/polyfill_2d.c @@ -841,9 +841,6 @@ static void polyfill_calc(PolyFill *pf) pf_triangulate(pf); } -/** - * A version of #BLI_polyfill_calc that uses a memory arena to avoid re-allocations. - */ void BLI_polyfill_calc_arena(const float (*coords)[2], const uint coords_tot, const int coords_sign, @@ -889,19 +886,6 @@ void BLI_polyfill_calc_arena(const float (*coords)[2], #endif } -/** - * Triangulates the given (convex or concave) simple polygon to a list of triangle vertices. - * - * \param coords: 2D coordinates describing vertices of the polygon, - * in either clockwise or counterclockwise order. - * \param coords_tot: Total points in the array. - * \param coords_sign: Pass this when we know the sign in advance to avoid extra calculations. - * - * \param r_tris: This array is filled in with triangle indices in clockwise order. - * The length of the array must be `coords_tot - 2`. - * Indices are guaranteed to be assigned to unique triangles, with valid indices, - * even in the case of degenerate input (self intersecting polygons, zero area ears... etc). - */ void BLI_polyfill_calc(const float (*coords)[2], const uint coords_tot, const int coords_sign, diff --git a/source/blender/blenlib/intern/polyfill_2d_beautify.c b/source/blender/blenlib/intern/polyfill_2d_beautify.c index ed07b002e32..684094234cf 100644 --- a/source/blender/blenlib/intern/polyfill_2d_beautify.c +++ b/source/blender/blenlib/intern/polyfill_2d_beautify.c @@ -92,21 +92,6 @@ BLI_INLINE bool is_boundary_edge(uint i_a, uint i_b, const uint coord_last) BLI_assert(i_a < i_b); return ((i_a + 1 == i_b) || UNLIKELY((i_a == 0) && (i_b == coord_last))); } -/** - * Assuming we have 2 triangles sharing an edge (2 - 4), - * check if the edge running from (1 - 3) gives better results. - * - * \param lock_degenerate: Use to avoid rotating out of a degenerate state: - * - When true, an existing zero area face on either side of the (2 - 4 - * split will return a positive value. - * - When false, the check must be non-biased towards either split direction. - * \param r_area: Return the area of the quad, - * This can be useful when comparing the return value with near zero epsilons. - * In this case the epsilon can be scaled by the area to avoid the return value - * of very large faces not having a reliable way to detect near-zero output. - * - * \return (negative number means the edge can be rotated, lager == better). - */ float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2], const float v2[2], const float v3[2], @@ -316,12 +301,6 @@ static void polyedge_rotate(struct HalfEdge *edges, struct HalfEdge *e) ed[3]->v = ed[2]->v; } -/** - * The intention is that this calculates the output of #BLI_polyfill_calc - * \note assumes the \a coords form a boundary, - * so any edges running along contiguous (wrapped) indices, - * are ignored since the edges won't share 2 faces. - */ void BLI_polyfill_beautify(const float (*coords)[2], const uint coords_tot, uint (*tris)[3], diff --git a/source/blender/blenlib/intern/rand.cc b/source/blender/blenlib/intern/rand.cc index 606d2611112..1d2274ede37 100644 --- a/source/blender/blenlib/intern/rand.cc +++ b/source/blender/blenlib/intern/rand.cc @@ -59,9 +59,6 @@ RNG *BLI_rng_new(unsigned int seed) return rng; } -/** - * A version of #BLI_rng_new that hashes the seed. - */ RNG *BLI_rng_new_srandom(unsigned int seed) { RNG *rng = new RNG(); @@ -84,9 +81,6 @@ void BLI_rng_seed(RNG *rng, unsigned int seed) rng->rng.seed(seed); } -/** - * Use a hash table to create better seed. - */ void BLI_rng_srandom(RNG *rng, unsigned int seed) { rng->rng.seed_random(seed); @@ -107,17 +101,11 @@ unsigned int BLI_rng_get_uint(RNG *rng) return rng->rng.get_uint32(); } -/** - * \return Random value (0..1), but never 1.0. - */ double BLI_rng_get_double(RNG *rng) { return rng->rng.get_double(); } -/** - * \return Random value (0..1), but never 1.0. - */ float BLI_rng_get_float(RNG *rng) { return rng->rng.get_float(); @@ -133,9 +121,6 @@ void BLI_rng_get_float_unit_v3(RNG *rng, float v[3]) copy_v3_v3(v, rng->rng.get_unit_float3()); } -/** - * Generate a random point inside given tri. - */ void BLI_rng_get_tri_sample_float_v2( RNG *rng, const float v1[2], const float v2[2], const float v3[2], float r_pt[2]) { @@ -190,11 +175,6 @@ void BLI_rng_shuffle_bitmap(struct RNG *rng, BLI_bitmap *bitmap, unsigned int bi } } -/** - * Simulate getting \a n random values. - * - * \note Useful when threaded code needs consistent values, independent of task division. - */ void BLI_rng_skip(RNG *rng, int n) { rng->rng.skip((uint)n); @@ -202,7 +182,6 @@ void BLI_rng_skip(RNG *rng, int n) /***/ -/* fill an array with random numbers */ void BLI_array_frand(float *ar, int count, unsigned int seed) { RNG rng; @@ -402,9 +381,6 @@ void BLI_hammersley_2d_sequence(unsigned int n, double *r) namespace blender { -/** - * Set a randomized hash of the value as seed. - */ void RandomNumberGenerator::seed_random(uint32_t seed) { this->seed(seed + hash[seed & 255]); @@ -434,9 +410,6 @@ float3 RandomNumberGenerator::get_unit_float3() return {0.0f, 0.0f, 1.0f}; } -/** - * Generate a random point inside the given triangle. - */ float2 RandomNumberGenerator::get_triangle_sample(float2 v1, float2 v2, float2 v3) { float u = this->get_float(); diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index 6bbe655b1cd..091945c9b12 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -39,13 +39,6 @@ /* avoid including BLI_math */ static void unit_m4(float m[4][4]); -/** - * Determine if a rect is empty. An empty - * rect is one with a zero (or negative) - * width or height. - * - * \return True if \a rect is empty. - */ bool BLI_rcti_is_empty(const rcti *rect) { return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin)); @@ -168,10 +161,6 @@ bool BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2]) return true; } -/** - * \returns shortest distance from \a rect to x/y (0 if inside) - */ - int BLI_rcti_length_x(const rcti *rect, const int x) { if (x < rect->xmin) { @@ -216,9 +205,6 @@ float BLI_rctf_length_y(const rctf *rect, const float y) return 0.0f; } -/** - * is \a rct_b inside \a rct_a - */ bool BLI_rctf_inside_rctf(const rctf *rct_a, const rctf *rct_b) { return ((rct_a->xmin <= rct_b->xmin) && (rct_a->xmax >= rct_b->xmax) && @@ -454,13 +440,6 @@ void BLI_rcti_init(rcti *rect, int xmin, int xmax, int ymin, int ymax) BLI_rcti_sanitize(rect); } -/** - * Check if X-min and Y-min are less than or equal to X-max and Y-max, respectively. - * If this returns false, #BLI_rctf_sanitize() can be called to address this. - * - * This is not a hard constraint or invariant for rectangles, in some cases it may be useful to - * have max < min. Usually this is what you'd want though. - */ bool BLI_rctf_is_valid(const rctf *rect) { return (rect->xmin <= rect->xmax) && (rect->ymin <= rect->ymax); @@ -471,9 +450,6 @@ bool BLI_rcti_is_valid(const rcti *rect) return (rect->xmin <= rect->xmax) && (rect->ymin <= rect->ymax); } -/** - * Ensure X-min and Y-min are less than or equal to X-max and Y-max, respectively. - */ void BLI_rctf_sanitize(rctf *rect) { if (rect->xmin > rect->xmax) { @@ -566,7 +542,6 @@ void BLI_rctf_do_minmax_v(rctf *rect, const float xy[2]) } } -/* given 2 rectangles - transform a point from one to another */ void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2], @@ -579,12 +554,6 @@ void BLI_rctf_transform_pt_v(const rctf *dst, xy_dst[1] = dst->ymin + ((dst->ymax - dst->ymin) * xy_dst[1]); } -/** - * Calculate a 4x4 matrix representing the transformation between two rectangles. - * - * \note Multiplying a vector by this matrix does *not* - * give the same value as #BLI_rctf_transform_pt_v. - */ void BLI_rctf_transform_calc_m4_pivot_min_ex( const rctf *dst, const rctf *src, float matrix[4][4], uint x, uint y) { @@ -631,7 +600,6 @@ void BLI_rctf_recenter(rctf *rect, float x, float y) BLI_rctf_translate(rect, dx, dy); } -/* change width & height around the central location */ void BLI_rcti_resize_x(rcti *rect, int x) { rect->xmin = BLI_rcti_cent_x(rect) - (x / 2); @@ -786,14 +754,6 @@ bool BLI_rcti_clamp_pt_v(const rcti *rect, int xy[2]) return changed; } -/** - * Clamp \a rect within \a rect_bounds, setting \a r_xy to the offset. - * - * Keeps the top left corner within the bounds, which for user interface - * elements is typically where the most important information is. - * - * \return true if a change is made. - */ bool BLI_rctf_clamp(rctf *rect, const rctf *rect_bounds, float r_xy[2]) { bool changed = false; @@ -1115,9 +1075,6 @@ void print_rcti(const char *str, const rcti *rect) } \ ((void)0) -/** - * Expand the rectangle to fit a rotated \a src. - */ void BLI_rctf_rotate_expand(rctf *dst, const rctf *src, const float angle) { const float mat2[2] = {sinf(angle), cosf(angle)}; diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c index 33c0f4afd01..89c2a695829 100644 --- a/source/blender/blenlib/intern/scanfill_utils.c +++ b/source/blender/blenlib/intern/scanfill_utils.c @@ -369,11 +369,6 @@ static bool scanfill_preprocess_self_isect(ScanFillContext *sf_ctx, return true; } -/** - * Call before scanfill to remove self intersections. - * - * \return false if no changes were made. - */ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx, ListBase *remvertbase, ListBase *remedgebase) diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c index 006a3798dcd..2278daf5516 100644 --- a/source/blender/blenlib/intern/smallhash.c +++ b/source/blender/blenlib/intern/smallhash.c @@ -214,7 +214,6 @@ void BLI_smallhash_init(SmallHash *sh) BLI_smallhash_init_ex(sh, 0); } -/* NOTE: does *not* free *sh itself! only the direct data! */ void BLI_smallhash_release(SmallHash *sh) { if (sh->buckets != sh->buckets_stack) { @@ -239,13 +238,6 @@ void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *item) e->val = item; } -/** - * Inserts a new value to a key that may already be in ghash. - * - * Avoids #BLI_smallhash_remove, #BLI_smallhash_insert calls (double lookups) - * - * \returns true if a new key has been added. - */ bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item) { SmallHashEntry *e = smallhash_lookup(sh, key); @@ -389,12 +381,6 @@ void BLI_smallhash_print(SmallHash *sh) #endif #ifdef DEBUG -/** - * Measure how well the hash function performs - * (1.0 is perfect - no stepping needed). - * - * Smaller is better! - */ double BLI_smallhash_calc_quality(SmallHash *sh) { uint64_t sum = 0; diff --git a/source/blender/blenlib/intern/stack.c b/source/blender/blenlib/intern/stack.c index 4a9bdd48a0a..629a6eaa78c 100644 --- a/source/blender/blenlib/intern/stack.c +++ b/source/blender/blenlib/intern/stack.c @@ -91,9 +91,6 @@ BLI_Stack *BLI_stack_new_ex(const size_t elem_size, return stack; } -/** - * Create a new homogeneous stack with elements of 'elem_size' bytes. - */ BLI_Stack *BLI_stack_new(const size_t elem_size, const char *description) { return BLI_stack_new_ex(elem_size, description, CHUNK_SIZE_DEFAULT); @@ -108,9 +105,6 @@ static void stack_free_chunks(struct StackChunk *data) } } -/** - * Free the stack's data and the stack itself - */ void BLI_stack_free(BLI_Stack *stack) { stack_free_chunks(stack->chunk_curr); @@ -118,12 +112,6 @@ void BLI_stack_free(BLI_Stack *stack) MEM_freeN(stack); } -/** - * Push a new item onto the stack. - * - * \return a pointer #BLI_Stack.elem_size - * bytes of uninitialized memory (caller must fill in). - */ void *BLI_stack_push_r(BLI_Stack *stack) { stack->chunk_index++; @@ -152,26 +140,12 @@ void *BLI_stack_push_r(BLI_Stack *stack) return stack_get_last_elem(stack); } -/** - * Copies the source value onto the stack - * - * \note This copies #BLI_Stack.elem_size bytes from \a src, - * (the pointer itself is not stored). - * - * \param src: source data to be copied to the stack. - */ void BLI_stack_push(BLI_Stack *stack, const void *src) { void *dst = BLI_stack_push_r(stack); memcpy(dst, src, stack->elem_size); } -/** - * Retrieves and removes the top element from the stack. - * The value is copies to \a dst, which must be at least \a elem_size bytes. - * - * Does not reduce amount of allocated memory. - */ void BLI_stack_pop(BLI_Stack *stack, void *dst) { BLI_assert(BLI_stack_is_empty(stack) == false); @@ -181,15 +155,6 @@ void BLI_stack_pop(BLI_Stack *stack, void *dst) BLI_stack_discard(stack); } -/** - * A version of #BLI_stack_pop which fills in an array. - * - * \param dst: The destination array, - * must be at least (#BLI_Stack.elem_size * \a n) bytes long. - * \param n: The number of items to pop. - * - * \note The first item in the array will be last item added to the stack. - */ void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n) { BLI_assert(n <= BLI_stack_count(stack)); @@ -200,11 +165,6 @@ void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n) } } -/** - * A version of #BLI_stack_pop_n which fills in an array (in the reverse order). - * - * \note The first item in the array will be first item added to the stack. - */ void BLI_stack_pop_n_reverse(BLI_Stack *stack, void *dst, unsigned int n) { BLI_assert(n <= BLI_stack_count(stack)); @@ -224,9 +184,6 @@ void *BLI_stack_peek(BLI_Stack *stack) return stack_get_last_elem(stack); } -/** - * Removes the top element from the stack. - */ void BLI_stack_discard(BLI_Stack *stack) { BLI_assert(BLI_stack_is_empty(stack) == false); @@ -247,9 +204,6 @@ void BLI_stack_discard(BLI_Stack *stack) } } -/** - * Discards all elements without freeing. - */ void BLI_stack_clear(BLI_Stack *stack) { #ifdef USE_TOTELEM @@ -304,9 +258,6 @@ size_t BLI_stack_count(const BLI_Stack *stack) #endif } -/** - * Returns true if the stack is empty, false otherwise - */ bool BLI_stack_is_empty(const BLI_Stack *stack) { #ifdef USE_TOTELEM diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 47bb2f0e8dd..c5e30ac6a6b 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -72,12 +72,6 @@ #include "BLI_string.h" #include "BLI_utildefines.h" -/** - * Copies the current working directory into *dir (max size maxncpy), and - * returns a pointer to same. - * - * \note can return NULL when the size is not big enough - */ char *BLI_current_working_dir(char *dir, const size_t maxncpy) { #if defined(WIN32) @@ -102,10 +96,6 @@ char *BLI_current_working_dir(char *dir, const size_t maxncpy) #endif } -/** - * Returns the number of free bytes on the volume containing the specified pathname. */ -/* Not actually used anywhere. - */ double BLI_dir_free_space(const char *dir) { #ifdef WIN32 @@ -201,9 +191,6 @@ int64_t BLI_lseek(int fd, int64_t offset, int whence) #endif } -/** - * Returns the file size of an opened file descriptor. - */ size_t BLI_file_descriptor_size(int file) { BLI_stat_t st; @@ -213,9 +200,6 @@ size_t BLI_file_descriptor_size(int file) return st.st_size; } -/** - * Returns the size of a file. - */ size_t BLI_file_size(const char *path) { BLI_stat_t stats; @@ -343,10 +327,6 @@ bool BLI_file_alias_target(const char *filepath, } #endif -/** - * Returns the st_mode from stat-ing the specified path name, or 0 if stat fails - * (most likely doesn't exist or no access). - */ int BLI_exists(const char *path) { #if defined(WIN32) @@ -430,18 +410,11 @@ int BLI_stat(const char *path, struct stat *buffer) } #endif -/** - * Does the specified path point to a directory? - * \note Would be better in fileops.c except that it needs stat.h so add here - */ bool BLI_is_dir(const char *file) { return S_ISDIR(BLI_exists(file)); } -/** - * Does the specified path point to a non-directory? - */ bool BLI_is_file(const char *path) { const int mode = BLI_exists(path); @@ -528,33 +501,6 @@ void *BLI_file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t return mem; } -/** - * Return the text file data with: - - * - Newlines replaced with '\0'. - * - Optionally trim white-space, replacing trailing <space> & <tab> with '\0'. - * - * This is an alternative to using #BLI_file_read_as_lines, - * allowing us to loop over lines without converting it into a linked list - * with individual allocations. - * - * \param trim_trailing_space: Replace trailing spaces & tabs with nil. - * This arguments prevents the caller from counting blank lines (if that's important). - * \param pad_bytes: When this is non-zero, the first byte is set to nil, - * to simplify parsing the file. - * It's recommended to pass in 1, so all text is nil terminated. - * - * Example looping over lines: - * - * \code{.c} - * size_t data_len; - * char *data = BLI_file_read_text_as_mem_with_newline_as_nil(filepath, true, 1, &data_len); - * char *data_end = data + data_len; - * for (char *line = data; line != data_end; line = strlen(line) + 1) { - * printf("line='%s'\n", line); - * } - * \endcode - */ void *BLI_file_read_text_as_mem_with_newline_as_nil(const char *filepath, bool trim_trailing_space, size_t pad_bytes, @@ -585,9 +531,6 @@ void *BLI_file_read_text_as_mem_with_newline_as_nil(const char *filepath, return mem; } -/** - * Reads the contents of a text file and returns the lines in a linked list. - */ LinkNode *BLI_file_read_as_lines(const char *filepath) { FILE *fp = BLI_fopen(filepath, "r"); @@ -634,15 +577,11 @@ LinkNode *BLI_file_read_as_lines(const char *filepath) return lines.list; } -/* - * Frees memory from a previous call to BLI_file_read_as_lines. - */ void BLI_file_free_lines(LinkNode *lines) { BLI_linklist_freeN(lines); } -/** is file1 older than file2 */ bool BLI_file_older(const char *file1, const char *file2) { #ifdef WIN32 diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 62c8625378d..35711c9432f 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -42,15 +42,6 @@ // #define DEBUG_STRSIZE -/** - * Duplicates the first \a len bytes of cstring \a str - * into a newly mallocN'd string and returns it. \a str - * is assumed to be at least len bytes long. - * - * \param str: The string to be duplicated - * \param len: The number of bytes to duplicate - * \retval Returns the duplicated string - */ char *BLI_strdupn(const char *str, const size_t len) { char *n = MEM_mallocN(len + 1, "strdup"); @@ -60,24 +51,11 @@ char *BLI_strdupn(const char *str, const size_t len) return n; } -/** - * Duplicates the cstring \a str into a newly mallocN'd - * string and returns it. - * - * \param str: The string to be duplicated - * \retval Returns the duplicated string - */ char *BLI_strdup(const char *str) { return BLI_strdupn(str, strlen(str)); } -/** - * Appends the two strings, and returns new mallocN'ed string - * \param str1: first string for copy - * \param str2: second string for append - * \retval Returns dst - */ char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) { /* include the NULL terminator of str2 only */ @@ -95,16 +73,6 @@ char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) return str; } -/** - * Like strncpy but ensures dst is always - * '\0' terminated. - * - * \param dst: Destination for copy - * \param src: Source string to copy - * \param maxncpy: Maximum number of characters to copy (generally - * the size of dst) - * \retval Returns dst - */ char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) { size_t srclen = BLI_strnlen(src, maxncpy - 1); @@ -119,16 +87,6 @@ char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t return dst; } -/** - * Like BLI_strncpy but ensures dst is always padded by given char, - * on both sides (unless src is empty). - * - * \param dst: Destination for copy - * \param src: Source string to copy - * \param pad: the char to use for padding - * \param maxncpy: Maximum number of characters to copy (generally the size of dst) - * \retval Returns dst - */ char *BLI_strncpy_ensure_pad(char *__restrict dst, const char *__restrict src, const char pad, @@ -171,19 +129,6 @@ char *BLI_strncpy_ensure_pad(char *__restrict dst, return dst; } -/** - * Like strncpy but ensures dst is always - * '\0' terminated. - * - * \note This is a duplicate of #BLI_strncpy that returns bytes copied. - * And is a drop in replacement for 'snprintf(str, sizeof(str), "%s", arg);' - * - * \param dst: Destination for copy - * \param src: Source string to copy - * \param maxncpy: Maximum number of characters to copy (generally - * the size of dst) - * \retval The number of bytes copied (The only difference from BLI_strncpy). - */ size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t maxncpy) { size_t srclen = BLI_strnlen(src, maxncpy - 1); @@ -205,9 +150,6 @@ size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) return srclen; } -/** - * Portable replacement for `vsnprintf`. - */ size_t BLI_vsnprintf(char *__restrict buffer, size_t maxncpy, const char *__restrict format, @@ -231,9 +173,6 @@ size_t BLI_vsnprintf(char *__restrict buffer, return n; } -/** - * A version of #BLI_vsnprintf that returns `strlen(buffer)` - */ size_t BLI_vsnprintf_rlen(char *__restrict buffer, size_t maxncpy, const char *__restrict format, @@ -258,9 +197,6 @@ size_t BLI_vsnprintf_rlen(char *__restrict buffer, return n; } -/** - * Portable replacement for #snprintf - */ size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...) { size_t n; @@ -277,9 +213,6 @@ size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict return n; } -/** - * A version of #BLI_snprintf that returns `strlen(dst)` - */ size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...) { size_t n; @@ -296,10 +229,6 @@ size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__res return n; } -/** - * Print formatted string into a newly #MEM_mallocN'd string - * and return it. - */ char *BLI_sprintfN(const char *__restrict format, ...) { DynStr *ds; @@ -318,18 +247,6 @@ char *BLI_sprintfN(const char *__restrict format, ...) return n; } -/** - * This roughly matches C and Python's string escaping with double quotes - `"`. - * - * Since every character may need escaping, - * it's common to create a buffer twice as large as the input. - * - * \param dst: The destination string, at least \a dst_maxncpy, typically `(strlen(src) * 2) + 1`. - * \param src: The un-escaped source string. - * \param dst_maxncpy: The maximum number of bytes allowable to copy. - * - * \note This is used for creating animation paths in blend files. - */ size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy) { @@ -381,18 +298,6 @@ BLI_INLINE bool str_unescape_pair(char c_next, char *r_out) return false; } -/** - * This roughly matches C and Python's string escaping with double quotes - `"`. - * - * The destination will never be larger than the source, it will either be the same - * or up to half when all characters are escaped. - * - * \param dst: The destination string, at least the size of `strlen(src) + 1`. - * \param src: The escaped source string. - * \param src_maxncpy: The maximum number of bytes allowable to copy from `src`. - * \param dst_maxncpy: The maximum number of bytes allowable to copy into `dst`. - * \param r_is_complete: Set to true when - */ size_t BLI_str_unescape_ex(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy, @@ -418,16 +323,6 @@ size_t BLI_str_unescape_ex(char *__restrict dst, return len; } -/** - * See #BLI_str_unescape_ex doc-string. - * - * This function makes the assumption that `dst` always has - * at least `src_maxncpy` bytes available. - * - * Use #BLI_str_unescape_ex if `dst` has a smaller fixed size. - * - * \note This is used for parsing animation paths in blend files (runs often). - */ size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy) { size_t len = 0; @@ -442,14 +337,6 @@ size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const return len; } -/** - * Find the first un-escaped quote in the string (to find the end of the string). - * - * \param str: Typically this is the first character in a quoted string. - * Where the character before `*str` would be `"`. - - * \return The pointer to the first un-escaped quote. - */ const char *BLI_str_escape_find_quote(const char *str) { bool escape = false; @@ -462,18 +349,6 @@ const char *BLI_str_escape_find_quote(const char *str) return (*str == '"') ? str : NULL; } -/** - * Return the range of the quoted string (excluding quotes) `str` after `prefix`. - * - * A version of #BLI_str_quoted_substrN that calculates the range - * instead of un-escaping and allocating the result. - * - * \param str: String potentially including `prefix`. - * \param prefix: Quoted string prefix. - * \param r_start: The start of the quoted string (after the first quote). - * \param r_end: The end of the quoted string (before the last quote). - * \return True when a quoted string range could be found after `prefix`. - */ bool BLI_str_quoted_substr_range(const char *__restrict str, const char *__restrict prefix, int *__restrict r_start, @@ -539,19 +414,6 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict } #endif -/** - * Fills \a result with text within "" that appear after some the contents of \a prefix. - * i.e. for string `pose["apples"]` with prefix `pose[`, it will return `apples`. - * - * \param str: is the entire string to chop. - * \param prefix: is the part of the string to step over. - * \param result: The buffer to fill. - * \param result_maxlen: The maximum size of the buffer (including nil terminator). - * \return True if the prefix was found and the entire quoted string was copied into result. - * - * Assume that the strings returned must be freed afterwards, - * and that the inputs will contain data we want. - */ bool BLI_str_quoted_substr(const char *__restrict str, const char *__restrict prefix, char *result, @@ -570,19 +432,6 @@ bool BLI_str_quoted_substr(const char *__restrict str, return is_complete; } -/** - * string with all instances of substr_old replaced with substr_new, - * Returns a copy of the c-string \a str into a newly #MEM_mallocN'd - * and returns it. - * - * \note A rather wasteful string-replacement utility, though this shall do for now... - * Feel free to replace this with an even safe + nicer alternative - * - * \param str: The string to replace occurrences of substr_old in - * \param substr_old: The text in the string to find and replace - * \param substr_new: The text in the string to find and replace - * \retval Returns the duplicated string - */ char *BLI_str_replaceN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new) @@ -638,13 +487,6 @@ char *BLI_str_replaceN(const char *__restrict str, return BLI_strdup(str); } -/** - * In-place replace every \a src to \a dst in \a str. - * - * \param str: The string to operate on. - * \param src: The character to replace. - * \param dst: The character to replace with. - */ void BLI_str_replace_char(char *str, char src, char dst) { while (*str) { @@ -655,13 +497,6 @@ void BLI_str_replace_char(char *str, char src, char dst) } } -/** - * Simple exact-match string replacement. - * - * \param replace_table: Array of source, destination pairs. - * - * \note Larger tables should use a hash table. - */ bool BLI_str_replace_table_exact(char *string, const size_t string_len, const char *replace_table[][2], @@ -678,19 +513,11 @@ bool BLI_str_replace_table_exact(char *string, /** \} */ -/** - * Compare two strings without regard to case. - * - * \retval True if the strings are equal, false otherwise. - */ int BLI_strcaseeq(const char *a, const char *b) { return (BLI_strcasecmp(a, b) == 0); } -/** - * Portable replacement for `strcasestr` (not available in MSVC) - */ char *BLI_strcasestr(const char *s, const char *find) { char c, sc; @@ -745,9 +572,6 @@ bool BLI_string_all_words_matched(const char *name, return all_words_matched; } -/** - * Variation of #BLI_strcasestr with string length limited to \a len - */ char *BLI_strncasestr(const char *s, const char *find, size_t len) { char c, sc; @@ -875,10 +699,6 @@ static int left_number_strcmp(const char *s1, const char *s2, int *tiebreaker) return 0; } -/** - * Case insensitive, *natural* string comparison, - * keeping numbers in order. - */ int BLI_strcasecmp_natural(const char *s1, const char *s2) { int d1 = 0, d2 = 0; @@ -946,10 +766,6 @@ int BLI_strcasecmp_natural(const char *s1, const char *s2) return strcmp(s1, s2); } -/** - * Like strcmp, but will ignore any heading/trailing pad char for comparison. - * So e.g. if pad is '*', '*world' and 'world*' will compare equal. - */ int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad) { size_t str1_len, str2_len; @@ -990,7 +806,6 @@ int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad) } } -/* determine the length of a fixed-size string */ size_t BLI_strnlen(const char *s, const size_t maxlen) { size_t len; @@ -1025,9 +840,6 @@ void BLI_str_toupper_ascii(char *str, const size_t len) } } -/** - * Strip white-space from end of the string. - */ void BLI_str_rstrip(char *str) { for (int i = (int)strlen(str) - 1; i >= 0; i--) { @@ -1040,15 +852,6 @@ void BLI_str_rstrip(char *str) } } -/** - * Strip trailing zeros from a float, eg: - * 0.0000 -> 0.0 - * 2.0010 -> 2.001 - * - * \param str: - * \param pad: - * \return The number of zeros stripped. - */ int BLI_str_rstrip_float_zero(char *str, const char pad) { char *p = strchr(str, '.'); @@ -1069,14 +872,6 @@ int BLI_str_rstrip_float_zero(char *str, const char pad) return totstrip; } -/** - * Return index of a string in a string array. - * - * \param str: The string to find. - * \param str_array: Array of strings. - * \param str_array_len: The length of the array, or -1 for a NULL-terminated array. - * \return The index of str in str_array or -1. - */ int BLI_str_index_in_array_n(const char *__restrict str, const char **__restrict str_array, const int str_array_len) @@ -1092,13 +887,6 @@ int BLI_str_index_in_array_n(const char *__restrict str, return -1; } -/** - * Return index of a string in a string array. - * - * \param str: The string to find. - * \param str_array: Array of strings, (must be NULL-terminated). - * \return The index of str in str_array or -1. - */ int BLI_str_index_in_array(const char *__restrict str, const char **__restrict str_array) { int index; @@ -1112,13 +900,6 @@ int BLI_str_index_in_array(const char *__restrict str, const char **__restrict s return -1; } -/** - * Find if a string starts with another string. - * - * \param str: The string to search within. - * \param start: The string we look for at the start. - * \return If str starts with start. - */ bool BLI_str_startswith(const char *__restrict str, const char *__restrict start) { for (; *str && *start; str++, start++) { @@ -1146,61 +927,22 @@ bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, s return false; } -/** - * Find if a string ends with another string. - * - * \param str: The string to search within. - * \param end: The string we look for at the end. - * \return If str ends with end. - */ bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) { const size_t slength = strlen(str); return BLI_strn_endswith(str, end, slength); } -/** - * Find the first char matching one of the chars in \a delim, from left. - * - * \param str: The string to search within. - * \param delim: The set of delimiters to search for, as unicode values. - * \param sep: Return value, set to the first delimiter found (or NULL if none found). - * \param suf: Return value, set to next char after the first delimiter found - * (or NULL if none found). - * \return The length of the prefix (i.e. *sep - str). - */ size_t BLI_str_partition(const char *str, const char delim[], const char **sep, const char **suf) { return BLI_str_partition_ex(str, NULL, delim, sep, suf, false); } -/** - * Find the first char matching one of the chars in \a delim, from right. - * - * \param str: The string to search within. - * \param delim: The set of delimiters to search for, as unicode values. - * \param sep: Return value, set to the first delimiter found (or NULL if none found). - * \param suf: Return value, set to next char after the first delimiter found - * (or NULL if none found). - * \return The length of the prefix (i.e. *sep - str). - */ size_t BLI_str_rpartition(const char *str, const char delim[], const char **sep, const char **suf) { return BLI_str_partition_ex(str, NULL, delim, sep, suf, true); } -/** - * Find the first char matching one of the chars in \a delim, either from left or right. - * - * \param str: The string to search within. - * \param end: If non-NULL, the right delimiter of the string. - * \param delim: The set of delimiters to search for, as unicode values. - * \param sep: Return value, set to the first delimiter found (or NULL if none found). - * \param suf: Return value, set to next char after the first delimiter found - * (or NULL if none found). - * \param from_right: If %true, search from the right of \a str, else, search from its left. - * \return The length of the prefix (i.e. *sep - str). - */ size_t BLI_str_partition_ex(const char *str, const char *end, const char delim[], @@ -1275,14 +1017,6 @@ static size_t BLI_str_format_int_grouped_ex(char src[16], char dst[16], int num_ return (size_t)(p_dst - dst); } -/** - * Format ints with decimal grouping. - * 1000 -> 1,000 - * - * \param dst: The resulting string - * \param num: Number to format - * \return The length of \a dst - */ size_t BLI_str_format_int_grouped(char dst[16], int num) { char src[16]; @@ -1291,14 +1025,6 @@ size_t BLI_str_format_int_grouped(char dst[16], int num) return BLI_str_format_int_grouped_ex(src, dst, num_len); } -/** - * Format uint64_t with decimal grouping. - * 1000 -> 1,000 - * - * \param dst: The resulting string - * \param num: Number to format - * \return The length of \a dst - */ size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num) { /* NOTE: Buffer to hold maximum unsigned int64, which is 1.8e+19. but @@ -1309,16 +1035,6 @@ size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num) return BLI_str_format_int_grouped_ex(src, dst, num_len); } -/** - * Format a size in bytes using binary units. - * 1000 -> 1 KB - * Number of decimal places grows with the used unit (e.g. 1.5 MB, 1.55 GB, 1.545 TB). - * - * \param dst: The resulting string. - * Dimension of 14 to support largest possible value for \a bytes (#LLONG_MAX). - * \param bytes: Number to format. - * \param base_10: Calculate using base 10 (GB, MB, ...) or 2 (GiB, MiB, ...). - */ void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base_10) { double bytes_converted = bytes; @@ -1345,24 +1061,6 @@ void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base BLI_strncpy(dst + len, base_10 ? units_base_10[order] : units_base_2[order], dst_len - len); } -/** - * Format a count to up to 6 places (plus '\0' terminator) string using long number - * names abbreviations. Used to produce a compact representation of large numbers. - * - * 1 -> 1 - * 15 -> 15 - * 155 -> 155 - * 1555 -> 1.6K - * 15555 -> 15.6K - * 155555 -> 156K - * 1555555 -> 1.6M - * 15555555 -> 15.6M - * 155555555 -> 156M - * 1000000000 -> 1B - * ... - * - * Length of 7 is the maximum of the resulting string, for example, `-15.5K\0`. - */ void BLI_str_format_attribute_domain_size(char dst[7], int number_to_format) { float number_to_format_converted = number_to_format; @@ -1384,16 +1082,6 @@ void BLI_str_format_attribute_domain_size(char dst[7], int number_to_format) BLI_snprintf(dst, dst_len, "%.*f%s", decimals, number_to_format_converted, units[order]); } -/** - * Find the ranges needed to split \a str into its individual words. - * - * \param str: The string to search for words. - * \param len: Size of the string to search. - * \param delim: Character to use as a delimiter. - * \param r_words: Info about the words found. Set to [index, len] pairs. - * \param words_max: Max number of words to find - * \return The number of words found in \a str - */ int BLI_string_find_split_words( const char *str, const size_t len, const char delim, int r_words[][2], int words_max) { diff --git a/source/blender/blenlib/intern/string_search.cc b/source/blender/blenlib/intern/string_search.cc index 08ba473f96b..02b0b814659 100644 --- a/source/blender/blenlib/intern/string_search.cc +++ b/source/blender/blenlib/intern/string_search.cc @@ -35,14 +35,6 @@ static int64_t count_utf8_code_points(StringRef str) return static_cast<int64_t>(BLI_strnlen_utf8(str.data(), static_cast<size_t>(str.size()))); } -/** - * Computes the cost of transforming string a into b. The cost/distance is the minimal number of - * operations that need to be executed. Valid operations are deletion, insertion, substitution and - * transposition. - * - * This function is utf8 aware in the sense that it works at the level of individual code points - * (1-4 bytes long) instead of on individual bytes. - */ int damerau_levenshtein_distance(StringRef a, StringRef b) { constexpr int deletion_cost = 1; @@ -106,10 +98,6 @@ int damerau_levenshtein_distance(StringRef a, StringRef b) return v1.last(); } -/** - * Returns -1 when this is no reasonably good match. - * Otherwise returns the number of errors in the match. - */ int get_fuzzy_match_errors(StringRef query, StringRef full) { /* If it is a perfect partial match, return immediately. */ @@ -346,10 +334,6 @@ static int score_query_against_words(Span<StringRef> query_words, Span<StringRef return total_match_score; } -/** - * Splits a string into words and normalizes them (currently that just means converting to lower - * case). The returned strings are allocated in the given allocator. - */ void extract_normalized_words(StringRef str, LinearAllocator<> &allocator, Vector<StringRef, 64> &r_words) @@ -417,10 +401,6 @@ StringSearch *BLI_string_search_new() return new StringSearch(); } -/** - * Add a new possible result to the search. - * The caller keeps ownership of all parameters. - */ void BLI_string_search_add(StringSearch *search, const char *str, void *user_data) { using namespace blender; @@ -431,11 +411,6 @@ void BLI_string_search_add(StringSearch *search, const char *str, void *user_dat {search->allocator.construct_array_copy(words.as_span()), (int)str_ref.size(), user_data}); } -/** - * Filter and sort all previously added search items. - * Returns an array containing the filtered user data. - * The caller has to free the returned array. - */ int BLI_string_search_query(StringSearch *search, const char *query, void ***r_data) { using namespace blender; diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index b9ea538ff24..807344a912c 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -42,9 +42,11 @@ // #define DEBUG_STRSIZE -/* array copied from glib's gutf8.c, */ -/* NOTE: last two values (0xfe and 0xff) are forbidden in utf-8, - * so they are considered 1 byte length too. */ +/** + * Array copied from GLIB's `gutf8.c`. + * \note last two values (0xfe and 0xff) are forbidden in UTF-8, + * so they are considered 1 byte length too. + */ static const size_t utf8_skip_data[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -56,22 +58,18 @@ static const size_t utf8_skip_data[256] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1, }; -/* from libswish3, originally called u8_isvalid(), - * modified to return the index of the bad character (byte index not utf). - * http://svn.swish-e.org/libswish3/trunk/src/libswish3/utf8.c r3044 - campbell */ - -/* based on the valid_utf8 routine from the PCRE library by Philip Hazel - * - * length is in bytes, since without knowing whether the string is valid - * it's hard to know how many characters there are! */ - -/** - * Find first utf-8 invalid byte in given \a str, of \a length bytes. - * - * \return the offset of the first invalid byte. - */ ptrdiff_t BLI_str_utf8_invalid_byte(const char *str, size_t length) { + /* NOTE(@campbellbarton): from libswish3, originally called u8_isvalid(), + * modified to return the index of the bad character (byte index not UTF). + * http://svn.swish-e.org/libswish3/trunk/src/libswish3/utf8.c r3044. + * + * Comment from code in: `libswish3`. + * Based on the `valid_utf8` routine from the PCRE library by Philip Hazel + * + * length is in bytes, since without knowing whether the string is valid + * it's hard to know how many characters there are! */ + const unsigned char *p, *perr, *pend = (const unsigned char *)str + length; unsigned char c; int ab; @@ -195,11 +193,6 @@ utf8_error: return ((const char *)perr - (const char *)str); } -/** - * Remove any invalid utf-8 byte (taking into account multi-bytes sequence of course). - * - * \return number of stripped bytes. - */ int BLI_str_utf8_invalid_strip(char *str, size_t length) { ptrdiff_t bad_char; @@ -312,7 +305,6 @@ size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, return len; } -/* wchar len in utf8 */ size_t BLI_wstrlen_utf8(const wchar_t *src) { size_t len = 0; @@ -362,11 +354,6 @@ size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_ return len; } -/** - * \param strc: the string to measure the length. - * \param maxlen: the string length (in bytes) - * \return the unicode length (not in bytes!) - */ size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen) { size_t len_bytes; @@ -389,8 +376,6 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, /* end wchar_t / utf8 functions */ /* --------------------------------------------------------------------------*/ -/* count columns that character/string occupies, based on wcwidth.c */ - int BLI_wcwidth(char32_t ucs) { return mk_wcwidth(ucs); @@ -475,10 +460,10 @@ int BLI_str_utf8_char_width_safe(const char *p) } \ (void)0 -/* uses glib functions but not from glib */ -/* gets the size of a single utf8 char */ int BLI_str_utf8_size(const char *p) { + /* NOTE: uses glib functions but not from GLIB. */ + int mask = 0, len; const unsigned char c = (unsigned char)*p; @@ -489,7 +474,6 @@ int BLI_str_utf8_size(const char *p) return len; } -/* use when we want to skip errors */ int BLI_str_utf8_size_safe(const char *p) { int mask = 0, len; @@ -502,21 +486,10 @@ int BLI_str_utf8_size_safe(const char *p) return len; } -/* was g_utf8_get_char */ -/** - * BLI_str_utf8_as_unicode: - * \param p: a pointer to Unicode character encoded as UTF-8 - * - * Converts a sequence of bytes encoded as UTF-8 to a Unicode character. - * If \a p does not point to a valid UTF-8 encoded character, results are - * undefined. If you are not sure that the bytes are complete - * valid Unicode characters, you should use g_utf8_get_char_validated() - * instead. - * - * Return value: the resulting character - */ uint BLI_str_utf8_as_unicode(const char *p) { + /* Originally `g_utf8_get_char` in GLIB. */ + int i, len; uint mask = 0; uint result; @@ -531,19 +504,6 @@ uint BLI_str_utf8_as_unicode(const char *p) return result; } -/** - * UTF8 decoding that steps over the index (unless an error is encountered). - * - * \param p: The text to step over. - * \param p_len: The length of `p`. - * \param index: Index of `p` to step over. - * \return the code-point or #BLI_UTF8_ERR if there is a decoding error. - * - * \note The behavior for clipped text (where `p_len` limits decoding trailing bytes) - * must have the same behavior is encountering a nil byte, - * so functions that only use the first part of a string has matching behavior to functions - * that null terminate the text. - */ uint BLI_str_utf8_as_unicode_step_or_error(const char *__restrict p, const size_t p_len, size_t *__restrict index) @@ -569,16 +529,6 @@ uint BLI_str_utf8_as_unicode_step_or_error(const char *__restrict p, return result; } -/** - * UTF8 decoding that steps over the index (unless an error is encountered). - * - * \param p: The text to step over. - * \param p_len: The length of `p`. - * \param index: Index of `p` to step over. - * \return the code-point `(p + *index)` if there is a decoding error. - * - * \note Falls back to `LATIN1` for text drawing. - */ uint BLI_str_utf8_as_unicode_step(const char *__restrict p, const size_t p_len, size_t *__restrict index) @@ -633,18 +583,6 @@ size_t BLI_str_utf8_from_unicode_len(const uint c) return len; } -/** - * BLI_str_utf8_from_unicode: - * - * \param c: a Unicode character code - * \param outbuf: output buffer, must have at least `outbuf_len` bytes of space. - * If the length required by `c` exceeds `outbuf_len`, - * the bytes available bytes will be zeroed and `outbuf_len` returned. - * - * Converts a single character to UTF-8. - * - * \return number of bytes written. - */ size_t BLI_str_utf8_from_unicode(uint c, char *outbuf, const size_t outbuf_len) { @@ -724,7 +662,6 @@ size_t BLI_str_utf32_as_utf8(char *__restrict dst, return len; } -/* utf32 len in utf8 */ size_t BLI_str_utf32_as_utf8_len(const char32_t *src) { size_t len = 0; @@ -736,24 +673,10 @@ size_t BLI_str_utf32_as_utf8_len(const char32_t *src) return len; } -/* was g_utf8_find_prev_char */ -/** - * BLI_str_find_prev_char_utf8: - * \param str: pointer to the beginning of a UTF-8 encoded string - * \param p: pointer to some position within \a str - * - * Given a position \a p with a UTF-8 encoded string \a str, find the start - * of the previous UTF-8 character starting before. \a p Returns \a str_start if no - * UTF-8 characters are present in \a str_start before \a p. - * - * \a p does not have to be at the beginning of a UTF-8 character. No check - * is made to see if the character found is actually valid other than - * it starts with an appropriate byte. - * - * \return A pointer to the found character. - */ const char *BLI_str_find_prev_char_utf8(const char *p, const char *str_start) { + /* Originally `g_utf8_find_prev_char` in GLIB. */ + BLI_assert(p >= str_start); if (str_start < p) { for (--p; p >= str_start; p--) { @@ -765,22 +688,10 @@ const char *BLI_str_find_prev_char_utf8(const char *p, const char *str_start) return p; } -/* was g_utf8_find_next_char */ -/** - * BLI_str_find_next_char_utf8: - * \param p: a pointer to a position within a UTF-8 encoded string - * \param end: a pointer to the byte following the end of the string. - * - * Finds the start of the next UTF-8 character in the string after \a p - * - * \a p does not have to be at the beginning of a UTF-8 character. No check - * is made to see if the character found is actually valid other than - * it starts with an appropriate byte. - * - * \return a pointer to the found character or a pointer to the null terminating character '\0'. - */ const char *BLI_str_find_next_char_utf8(const char *p, const char *str_end) { + /* Originally `g_utf8_find_next_char` in GLIB. */ + BLI_assert(p <= str_end); if ((p < str_end) && (*p != '\0')) { for (++p; p < str_end && (*p & 0xc0) == 0x80; p++) { diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c index b62b9c3bc7a..21162904dbd 100644 --- a/source/blender/blenlib/intern/string_utils.c +++ b/source/blender/blenlib/intern/string_utils.c @@ -38,20 +38,6 @@ # pragma GCC diagnostic error "-Wsign-conversion" #endif -/** - * Looks for a numeric suffix preceded by delim character on the end of - * name, puts preceding part into *left and value of suffix into *nr. - * Returns the length of *left. - * - * Foo.001 -> "Foo", 1 - * Returning the length of "Foo" - * - * \param left: Where to return copy of part preceding delim - * \param nr: Where to return value of numeric suffix - * \param name: String to split - * \param delim: Delimiter character - * \return Length of \a left - */ size_t BLI_split_name_num(char *left, int *nr, const char *name, const char delim) { const size_t name_len = strlen(name); @@ -102,10 +88,6 @@ static bool is_char_sep(const char c) return ELEM(c, '.', ' ', '-', '_'); } -/** - * based on `BLI_split_dirfile()` / `os.path.splitext()`, - * `"a.b.c"` -> (`"a.b"`, `".c"`). - */ void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, const size_t str_len) { size_t len = BLI_strnlen(string, str_len); @@ -124,9 +106,6 @@ void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, cons memcpy(r_body, string, len + 1); } -/** - * `"a.b.c"` -> (`"a."`, `"b.c"`) - */ void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, const size_t str_len) { size_t len = BLI_strnlen(string, str_len); @@ -146,17 +125,6 @@ void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, cons BLI_strncpy(r_body, string, len); } -/** - * Finds the best possible flipped (left/right) name. - * For renaming; check for unique names afterwards. - * - * \param r_name: flipped name, - * assumed to be a pointer to a string of at least \a name_len size. - * \param from_name: original name, - * assumed to be a pointer to a string of at least \a name_len size. - * \param strip_number: If set, remove number extensions. - * \return The number of bytes written into \a r_name. - */ size_t BLI_string_flip_side_name(char *r_name, const char *from_name, const bool strip_number, @@ -278,18 +246,6 @@ size_t BLI_string_flip_side_name(char *r_name, /* Unique name utils. */ -/** - * Ensures name is unique (according to criteria specified by caller in unique_check callback), - * incrementing its numeric suffix as necessary. Returns true if name had to be adjusted. - * - * \param unique_check: Return true if name is not unique - * \param arg: Additional arg to unique_check--meaning is up to caller - * \param defname: To initialize name if latter is empty - * \param delim: Delimits numeric suffix in name - * \param name: Name to be ensured unique - * \param name_len: Maximum length of name area - * \return true if there if the name was changed - */ bool BLI_uniquename_cb(UniquenameCheckCallback unique_check, void *arg, const char *defname, @@ -366,17 +322,6 @@ static bool uniquename_unique_check(void *arg, const char *name) return uniquename_find_dupe(data->lb, data->vlink, name, data->name_offset); } -/** - * Ensures that the specified block has a unique name within the containing list, - * incrementing its numeric suffix as necessary. Returns true if name had to be adjusted. - * - * \param list: List containing the block - * \param vlink: The block to check the name for - * \param defname: To initialize block name if latter is empty - * \param delim: Delimits numeric suffix in name - * \param name_offset: Offset of name within block structure - * \param name_len: Maximum length of name area - */ bool BLI_uniquename( ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_len) { @@ -432,9 +377,6 @@ char *BLI_string_join_array(char *result, return c; } -/** - * A version of #BLI_string_join that takes a separator which can be any character including '\0'. - */ char *BLI_string_join_array_by_sep_char( char *result, size_t result_len, char sep, const char *strings[], uint strings_len) { @@ -455,9 +397,6 @@ char *BLI_string_join_array_by_sep_char( return c; } -/** - * Join an array of strings into a newly allocated, null terminated string. - */ char *BLI_string_join_arrayN(const char *strings[], uint strings_len) { uint total_len = 1; @@ -474,9 +413,6 @@ char *BLI_string_join_arrayN(const char *strings[], uint strings_len) return result; } -/** - * A version of #BLI_string_joinN that takes a separator which can be any character including '\0'. - */ char *BLI_string_join_array_by_sep_charN(char sep, const char *strings[], uint strings_len) { uint total_len = 0; @@ -501,10 +437,6 @@ char *BLI_string_join_array_by_sep_charN(char sep, const char *strings[], uint s return result; } -/** - * A version of #BLI_string_join_array_by_sep_charN that takes a table array. - * The new location of each string is written into this array. - */ char *BLI_string_join_array_by_sep_char_with_tableN(char sep, char *table[], const char *strings[], diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c index 66d0b44cfb3..e64d53467e4 100644 --- a/source/blender/blenlib/intern/system.c +++ b/source/blender/blenlib/intern/system.c @@ -73,9 +73,6 @@ int BLI_cpu_support_sse2(void) /* Windows stack-walk lives in system_win32.c */ #if !defined(_MSC_VER) -/** - * Write a backtrace into a file for systems which support it. - */ void BLI_system_backtrace(FILE *fp) { /* ------------- */ diff --git a/source/blender/blenlib/intern/system_win32.c b/source/blender/blenlib/intern/system_win32.c index f65234b656b..b2360cf743f 100644 --- a/source/blender/blenlib/intern/system_win32.c +++ b/source/blender/blenlib/intern/system_win32.c @@ -373,6 +373,9 @@ static void bli_load_symbols() } } +/** + * Write a backtrace into a file for systems which support it. + */ void BLI_system_backtrace(FILE *fp) { SymInitialize(GetCurrentProcess(), NULL, TRUE); diff --git a/source/blender/blenlib/intern/task_iterator.c b/source/blender/blenlib/intern/task_iterator.c index 6378d88e2b1..fddd9a799ec 100644 --- a/source/blender/blenlib/intern/task_iterator.c +++ b/source/blender/blenlib/intern/task_iterator.c @@ -332,17 +332,6 @@ static void task_parallel_listbase_get(void *__restrict UNUSED(userdata), (*r_next_index)++; } -/** - * This function allows to parallelize for loops over ListBase items. - * - * \param listbase: The double linked list to loop over. - * \param userdata: Common userdata passed to all instances of \a func. - * \param func: Callback function. - * \param settings: See public API doc of ParallelRangeSettings for description of all settings. - * - * \note There is no static scheduling here, - * since it would need another full loop over items to count them. - */ void BLI_task_parallel_listbase(ListBase *listbase, void *userdata, TaskParallelIteratorFunc func, @@ -388,16 +377,6 @@ static void parallel_mempool_func(TaskPool *__restrict pool, void *taskdata) } } -/** - * This function allows to parallelize for loops over Mempool items. - * - * \param mempool: The iterable BLI_mempool to loop over. - * \param userdata: Common userdata passed to all instances of \a func. - * \param func: Callback function. - * \param settings: See public API doc of TaskParallelSettings for description of all settings. - * - * \note There is no static scheduling here. - */ void BLI_task_parallel_mempool(BLI_mempool *mempool, void *userdata, TaskParallelMempoolFunc func, diff --git a/source/blender/blenlib/intern/threads.cc b/source/blender/blenlib/intern/threads.cc index 15bdb08f89f..3589c952409 100644 --- a/source/blender/blenlib/intern/threads.cc +++ b/source/blender/blenlib/intern/threads.cc @@ -152,10 +152,6 @@ void BLI_threadapi_exit() { } -/* tot = 0 only initializes malloc mutex in a safe way (see sequence.c) - * problem otherwise: scene render will kill of the mutex! - */ - void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int tot) { int a; @@ -189,7 +185,6 @@ void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int t } } -/* amount of available threads */ int BLI_available_threads(ListBase *threadbase) { int counter = 0; @@ -203,7 +198,6 @@ int BLI_available_threads(ListBase *threadbase) return counter; } -/* returns thread number, for sample patterns or threadsafe tables */ int BLI_threadpool_available_thread_index(ListBase *threadbase) { int counter = 0; @@ -305,7 +299,6 @@ void BLI_threadpool_end(ListBase *threadbase) /* System Information */ -/* how many threads are native on this system? */ int BLI_system_thread_count() { static int t = -1; diff --git a/source/blender/blenlib/intern/timecode.c b/source/blender/blenlib/intern/timecode.c index 13f95ddf264..55131fa639d 100644 --- a/source/blender/blenlib/intern/timecode.c +++ b/source/blender/blenlib/intern/timecode.c @@ -35,19 +35,6 @@ #include "BLI_strict_flags.h" -/** - * Generate time-code/frame number string and store in \a str - * - * \param str: destination string - * \param maxncpy: maximum number of characters to copy `sizeof(str)` - * \param brevity_level: special setting for #View2D grid drawing, - * used to specify how detailed we need to be - * \param time_seconds: time total time in seconds - * \param fps: frames per second, typically from the #FPS macro - * \param timecode_style: enum from #eTimecodeStyles - * \return length of \a str - */ - size_t BLI_timecode_string_from_time(char *str, const size_t maxncpy, const int brevity_level, @@ -195,14 +182,6 @@ size_t BLI_timecode_string_from_time(char *str, return rlen; } -/** - * Generate time string and store in \a str - * - * \param str: destination string - * \param maxncpy: maximum number of characters to copy `sizeof(str)` - * \param time_seconds: time total time in seconds - * \return length of \a str - */ size_t BLI_timecode_string_from_time_simple(char *str, const size_t maxncpy, const double time_seconds) @@ -225,18 +204,6 @@ size_t BLI_timecode_string_from_time_simple(char *str, return rlen; } -/** - * Generate time string and store in \a str - * - * \param str: destination string - * \param maxncpy: maximum number of characters to copy `sizeof(str)` - * \param brevity_level: special setting for #View2D grid drawing, - * used to specify how detailed we need to be - * \param time_seconds: time total time in seconds - * \return length of \a str - * - * \note in some cases this is used to print non-seconds values. - */ size_t BLI_timecode_string_from_time_seconds(char *str, const size_t maxncpy, const int brevity_level, diff --git a/source/blender/blenlib/intern/uvproject.c b/source/blender/blenlib/intern/uvproject.c index 093d08e643d..dbab0162eba 100644 --- a/source/blender/blenlib/intern/uvproject.c +++ b/source/blender/blenlib/intern/uvproject.c @@ -90,7 +90,6 @@ void BLI_uvproject_from_camera(float target[2], float source[3], ProjCameraInfo target[1] += uci->shifty; } -/* could rv3d->persmat */ void BLI_uvproject_from_view(float target[2], float source[3], float persmat[4][4], @@ -132,8 +131,6 @@ void BLI_uvproject_from_view(float target[2], target[1] = (y + target[1]) / winy; } -/* 'rotmat' can be `obedit->obmat` when uv project is used. - * 'winx' and 'winy' can be from `scene->r.xsch/ysch` */ ProjCameraInfo *BLI_uvproject_camera_info(Object *ob, float rotmat[4][4], float winx, float winy) { ProjCameraInfo uci; diff --git a/source/blender/blenlib/intern/voxel.c b/source/blender/blenlib/intern/voxel.c index c0c895654e3..a2b29ce1185 100644 --- a/source/blender/blenlib/intern/voxel.c +++ b/source/blender/blenlib/intern/voxel.c @@ -35,7 +35,7 @@ BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z) } /* *** nearest neighbor *** */ -/* input coordinates must be in bounding box 0.0 - 1.0 */ + float BLI_voxel_sample_nearest(const float *data, const int res[3], const float co[3]) { int xi, yi, zi; |