There is no advantage in using BLI_strncpy/BLI_strncpy_utf8 when the
destination string has been allocated and won't be concatenated.
Also no need to calloc memory which is filled by strcpy afterwards.
- Names ending with len sometimes referred to the buffer size.
The same names were used for both buffer size and string length
depending on the function in some cases.
- Rename str/string to path for generic path functions.
- Rename BLI_path_rel arguments (file, relfile) to (path, basename)
as it wasn't so clear which is being made relative, `file` can be a
directory so rename to `path` (matches naming for BLI_path_abs).
- Avoid inline ifdef checks for DEBUG_STRSIZE
- Add BLI_string_debug_size_after_nil to ensure strings to manipulate
have the expected buffer size after the nil terminator.
- Add checks to more string manipulation functions.
Further changes are required for this to be enabled during regular
development as the RNA currently allocates the strings length but
passes in the buffer size as a limit which conflicts with DEBUG_STRSIZE.
- Rename name/filename/path to filepath when it's used for full paths.
- Rename name/path to dirpath when it refers to a directory.
- Rename file to filepath or path (when it may be a file or dir).
- Rename ImBuf::name & anim::name to filepath.
Rename BLI_make_existing_file to BLI_file_ensure_parent_dir_exists.
The previous name read as if it would make (touch) the file,
where as it ensures the directory component of the path exists.
Move from BLI_path to BLI_fileops as path utilities should only
manipulate paths and not deal with file IO creation
(this has more in common with BLI_file_touch for e.g.).
A NULL defname would early exit (doing nothing) this isn't good behavior
as this function should always make the name unique and a NULL defname
is likely an error in the code which would allow duplicate names.
This is also inconsistent with BLI_uniquename_cb which always
wrote the defname into the name if it was empty.
Mark this argument as never-NULL.
This fixes a crash where merging vertices by distance leads to a crash since
0652945dbd. The change did not cause
the bug though, it just made the underlying issue visible.
The issue was that `kdtree_order` assumed that the `KDTreeNode.index` didn't
have gaps, i.e. every index in a certain range is used. However, that is not the
case when only a subset of the vertices of a mesh are added to the kdtree.
Pull Request: https://projects.blender.org/blender/blender/pulls/107535
Most of this patch is by Jacques Lucke, from the simulation branch.
This commit adds generic expression evaluation for bit spans, helping
to generalize the optimizations that avoid processing a single bit
at a time. Operations like "for each 1 index", "or", and "and" are
already implemented in this pull request. Bits in full integers are
processed 64 at a time, then remaining bits are processed all at once.
The operations allow implementing a `copy_from` method for bit spans.
Currently this optimized evaluation is only implemented for simpler
bounded bit spans. Bounded bit spans have constraints on their bit
ranges that make them more efficient to process. Large spans must start
at the beginning of the first int, and small spans must start and end
within the first int.
Knowing these constraints at compile time reduces the number of edge
cases in the operations, but mainly allows skipping alignment between
multiple spans with different offsets.
Pull Request: https://projects.blender.org/blender/blender/pulls/107408
This simplifies the code that works with the `BLI_serialize.hh` header.
The various `lookup` methods do a linear search. If there are only a
few elements that can even be faster than building the map first.
In the future it might be nice to transparently build and cache the
map internally if necessary.
The main goal of these changes is to support checking if some data has
been changed over time. This is used by the WIP simulation nodes during
baking to detect which attributes have to be stored in every frame because
they have changed.
By using a combination of a weak user count and a version counter, it is
possible to detect that an attribute (or any data controlled by implicit
sharing) has not been changed with O(1) memory and time. It's still
possible that the data has been changed multiple times and is the same
in the end and beginning of course. That wouldn't be detected using this
mechanism.
The `ImplicitSharingInfo` struct has a new weak user count. A weak
reference is one that does not keep the referenced data alive, but makes sure
that the `ImplicitSharingInfo` itself is not deleted. If some piece of
data has one strong and multiple weak users, it is still mutable. If the
strong user count goes down to zero, the referenced data is freed.
Remaining weak users can check for this condition using `is_expired`.
This is a bit similar to `std::weak_ptr` but there is an important difference:
a weak user can not become a strong user while one can create a `shared_ptr`
from a `weak_ptr`. This restriction is necessary, because some code might
be changing the referenced data assuming that it is the only owner. If
another thread suddenly adds a new owner, the data would be shared again
and the first thread would not have been allowed to modify the data in
the first place.
There is also a new integer version counter in `ImplicitSharingInfo`.
It is incremented whenever some code wants to modify the referenced data.
Obviously, this can only be done when the data is not shared because then
it would be immutable. By comparing an old and new version number of the
same sharing info, one can check if the data has been modified. One has
to keep a weak reference to the sharing info together with the old version
number to ensure that the new sharing info is still the same as the old one.
Without this, it can happen that the sharing info was freed and a new
one was allocated at the same pointer address. Using a strong reference
for this purpose does not work, because then the data would never be
modified because it's shared.
- Avoid a separate memmove call for each `..`.
- Avoid ambiguous path stepping, where separator literals
needed to be checked to avoid fence post errors.
- Correct & update the doc-string.
This patch adds address sanitizer support to memory pools.
when ASAN is enabled the following happens:
* 32 byte red zones are inserted between pool elements.
* The BLI_mempool struct itself is marked as a red zone.
* Access to the pool goes through a thread mutex (except when compiling makesdna).
This is very useful for finding bugs in code that uses BMesh.
Pull Request: #104668
Keep these operations separate to simplify path handling logic & docs.
Many callers passed NULL and there were times paths were passed in which
didn't make any sense (where the paths had already been made absolute).
- Don't attempt to skip the WIN32 drive component on relative paths
it's possible this would have unexpected behavior but paths like
are already unlikely to work as expected, e.g. "//C:\".
- Remove early returns for empty paths as there is no need for special
handling.
- Add path normalize NOP tests
Follow Python's os.path.normpath's handing on relative paths in more
situations.
- Leading './' is always stripped.
- Relative paths such as `//./a` & `///a` normalize to `//a`.
- Support for trailing `/..` on the end of paths.
- Avoid empty paths for relative paths that would otherwise
resolve to an empty string, e.g: `a/b/c/../../..` resolves to `.`.
- Calculate spans of redundant `//` & `/./` before calling `memmove`.
- Loop backwards when removing path elements for greater efficiency.
- When removing `/../` components, avoid continuously searching from
the start of the path and instead search from the last found '/../'.
The only WIN32 specific behavior the drive or UNC prefix is skipped
(except for it's slash), allowing WIN32 & Unix paths to share the same
code-path.
Note that this changes behavior for WIN32 when there are too many parent
directories, where ".." that move before the root directory are removed
instead of being left in the path. e.g:
`C:\a\..\..\b` resolved to `C:\..\b` whereas now the result is `C:\b`.
This matches Python's `os.path.normpath`.
The result of detecting if a quad should flip the default 0-2 split
when tessellated only used a pre-calculated normal when available,
since the method of detecting the flip was different, the check for a
concave face could change depending on the existence of polygon-normals.
In practice this meant cycles render preview could use a different
tessellation than the GPU display.
While [0] exposed the bug, it's an inherent problem with having 2
methods of detecting concave quads.
Remove is_quad_flip_v3_first_third_fast_with_normal(..) and always
use is_quad_flip_v3_first_third_fast(..), because having to calculate
the normal inline has significant overhead.
Note that "bow-tie" quads may now render with a subdivision in a
different direction although they must be very distorted with both
triangles along the 0-2 split pointing away from each other.
Thanks to @HooglyBoogly for investigating the issue.
[0]: 16fbadde36.
Generally, one does not know if the sharing info is currently shared
and should therefore be const. Better keep it const almost all the
time and only remove the constness when absolutely necessary
and the code has checked that it is valid.
Some callers that access the extension operated on the end of the path
even when there was no extension. Using this avoids having to assign
the end of the string using a separate check.
The file extension was copied into a buffer without checking it's size.
While large extensions aren't typical, some callers used small fixed
size buffers so an unusually named file could crash.