65 Commits

Author SHA1 Message Date
Sybren A. Stüvel
f9bc6f2d08 Cleanup: fix mypy errors
This mostly handles a mypy change where implicit optionals (i.e. things
like `size: int = None`) are no longer allowed.

No functional changes.
2023-11-02 14:46:38 +01:00
Sybren A. Stüvel
b3fb7845c3 Cleanup: Reformat with black
No functional changes.
2023-11-02 14:40:27 +01:00
Sybren A. Stüvel
055457ab67 Add BlendFileBlock.raw_data() and .as_string() functions
Add functions to interpret the data in a `BlendFileBlock` as either `bytes`
or `string`. This is used to obtain the contents of a `char*` (instead
of an embedded `char[N]` array).
2023-05-16 16:01:38 +02:00
Sybren A. Stüvel
63c4745e9f Cleanup: reformat with Black 2022-03-25 12:07:06 +01:00
Sybren A. Stüvel
973bf741c7 Cleanup: add a comment to explain EndianIO::accepted_types
No functional changes.
2022-03-25 12:07:06 +01:00
William Harrell
6bfa4062d7 Support for int, float types in BlendFileBlock.set
---

The blendfile module within BAT supports reading data from structs, such
as the Count property on an array modifier. However, blendfile only
supports modifying structs with type "char". This patch adds support for
writing structs of more types in blendfile blocks. Now, writing is
supported for ushort, short, uint, int, float, and ulong types.

The use case that inspired this patch was an instance where a file had
several array modifiers that prevented the file from being opened in
Blender on machines without large amounts of RAM. A solution using the
blendfile module may look like:

```
from blender_asset_tracer import blendfile
from pathlib import Path

b = blendfile.open_cached(Path('flag.blend'), mode='rb+')

for block in b.blocks:
    if 'ArrayModifierData' in block.__str__():
        try:
            print('previous:', block.get(b'count'))
            block.set(b'count', 1)
            print('current:', block.get(b'count'))
        except KeyError:
            continue

b.close()
```

This would fail with the exception
`blender_asset_tracer.blendfile.exceptions.NoWriterImplemented: Setting
type Struct(b'int') is not supported for ArrayModifierData.count`. With
this patch, the above code succeeds and the count struct can be set to
a lower number that allows the file to be opened.

This solution implements missing functionality without adding any new
interfaces. A few details are:
* When deciding what type to write to the struct, the value is inferred
from what is given by the caller. If the caller gives a Python int, the
exact type is inferred from the DNA type ID. If they give a float, a
float is written. Otherwise, the existing logic is used to determine
whether to write a string or byte sequence.
* A \_write method was added to dna\_io.py that takes a Python struct
object and a value to write a byte sequence to the file object. This
method is used by public methods appropriately named to indicate what
type they will write.
* The check for whether the caller is trying to write an unsupported
type is left in place, but it has been changed to include types which
are now supported.
* Tests have been added that provide a mock file object, call the new
methods, and confirm that the correct bytes were written.

Reviewed By: sybren

Differential Revision: https://developer.blender.org/D14374
2022-03-25 12:07:06 +01:00
Sybren A. Stüvel
e5c7e38b44 Avoid doubly-compressing zstandard files 2022-02-03 17:54:03 +01:00
Ethan Simon
608a7bdac9 Compatibility with packing read-only source files
File permissions are no longer copied when packing. This means that
read-only source files can still be packed without errors, even when
they have to be rewritten (due to changed paths).

Reviewed by: sybren

Differential Revision: https://developer.blender.org/D13128
2021-11-09 11:15:20 +01:00
Sybren A. Stüvel
8a06bf5903 Add optional support for ZStandard compression
BAT now can take advantage of the `zstandard` module to handle Blender
3.0+ compressed blend files.

If the module is not installed, the blend files cannot be opened but
GZip-compressed and uncompressed files can still be handled.
2021-10-05 18:24:44 +02:00
Paul Golter
db26a0aaf1 Add log warning if SegmentationFault caused by dereferencing invalid pointer is silenced when strict_pointer_mode is turned off. 2021-07-22 15:58:44 +02:00
Sybren A. Stüvel
bd9ec7ddc7 Control Strict Pointer Mode from the CLI, defaulting to OFF
Due to issues with library overrides and unsynced pointers, it's quite
common for the Blender Animation Studio to get crashes of BAT. To avoid
these, Strict Pointer Mode is disabled when using BAT from the CLI.

Blender Cloud add-on will also get a similar update, so that there also
the Strict Pointer Mode is disabled.
2021-07-22 10:47:50 +02:00
Sybren A. Stüvel
087ff25c76 Add 'strict pointer mode' to BlendFile
Add a 'strict pointer mode' to the `BlendFile` class, which is enabled
by default. This allows users of the `BlendFile` class to decide whether
a bad pointer (i.e. one that points to a non-existing datablock) returns
`None` or raises a `SegmentationFault` exception.
2021-07-22 10:28:48 +02:00
Sybren A. Stüvel
803c38dac1 Cleanup: reformat with Black 2021-07-22 10:14:43 +02:00
Sybren A. Stüvel
23dea91572 Add support for indirectly linked Geometry Nodes node trees 2021-02-02 13:41:39 +01:00
Sybren A. Stüvel
e4bf2e8e35 Improved path handling
This commit fixes a bunch of issues at the same time, as they are all
related to path handling:

- `pathlib.Path.resolve()` or `.absolute()` are replaced by
  `bpathlib.make_absolute()`. The latter does NOT follow symlinks and does
  NOT network mounts from a drive letter to UNC notation. This also has
  advantages on non-Windows sytems, as it allows BAT-packing a directory
  structure with symlinked files (such as a Shaman checkout).
- Better handling of drive letters, and of paths that cross drive
  boundaries.
- Better testing of Windows-specific cases when running the tests on
  Windows, and of POSIX-specific cases on other platforms.

Thanks to @wisaac for starting this patch in D6676.

Thanks to @jbakker for pointing out the drive letter issue. This fixes
T70655.
2020-03-17 17:15:19 +01:00
Sybren A. Stüvel
66681a69df Fixed crash where collection children are ID blocks instead of GR blocks
Not sure when/how that happens, but it happened on a lighting file of the
Spring project, when linking in a nested collection of which parts where
also linked in from other blend files.
2019-02-12 12:31:05 +01:00
Sybren A. Stüvel
4bc5484c23 Fixed MyPy issue 2018-12-20 14:23:06 +01:00
Sybren A. Stüvel
38b3e2b55c Fixed a whole bunch of MyPy errors
New release of mypy picks up more.
2018-07-10 16:02:14 +02:00
Sybren A. Stüvel
6edc15594d Added utility function to fetching structs by name 2018-07-03 12:34:00 +02:00
Sybren A. Stüvel
5f966934df Blender 2.8 fixes because of removed Material.mtex and Material.group 2018-06-07 15:18:18 +02:00
Sybren A. Stüvel
8b73b86734 Reduce cyclomatic complexity of Struct.field_get() 2018-03-22 10:56:02 +01:00
Sybren A. Stüvel
53e22a4a2f Added GPL comment blocks with proper attibution. 2018-03-16 13:25:20 +01:00
Sybren A. Stüvel
cc06a191a1 Added more annotations for mypy
Function declarations that have no type annotations at all will be skipped
by mypy. Adding an explicit `-> None` tells mypy to run on those functions
too.
2018-03-09 14:23:43 +01:00
Sybren A. Stüvel
824ca4bcb7 Rewrite blend files in temporary directory, before copying
This allows us to later support uploading to a non-local filesystem, such
as Amazon S3 cloud storage, after path rewriting is complete.
2018-03-09 12:33:15 +01:00
Sybren A. Stüvel
fdbbc3a20d Static type checking with mypy
This does introduce some not-so-nice things, like having to annotate each
`__init__` function with `-> None`. However, the benefits of having static
type checking in a complex bit of software like BAT outweigh the downsides.
2018-03-09 11:09:47 +01:00
Sybren A. Stüvel
e03e0fb4d7 Reduced some log levels 2018-03-08 14:53:25 +01:00
Sybren A. Stüvel
0dab872289 Truncate UTF-8 in a way that produces valid UTF-8. 2018-03-08 14:47:41 +01:00
Sybren A. Stüvel
f2f824ad85 Speed up BlendFileBlock instantiation with __slots__
Due to the huge number of BlendFileBlock objects created for packing a
production-size blend file, using slots here actually makes the
dependency tracer significantly (p<0.001) faster. In my test case the
speed improvement was 16% for a 'bam list' command.
2018-03-08 13:59:28 +01:00
Sybren A. Stüvel
9af913d69a Removed find_block_from_address() in favour of dereference_pointer() 2018-03-08 11:08:36 +01:00
Sybren A. Stüvel
ccdccd69cf Speed up rewriting paths by reusing cached DNA structs & blocks 2018-03-08 10:59:45 +01:00
Sybren A. Stüvel
cc20b0bfd5 Sort queue of blocks to visit by blend file and on-disk order
This gives a small speedup to dependency tracing.
2018-03-07 17:14:35 +01:00
Sybren A. Stüvel
09a0866c14 Cache open blend files
This simplifies blend file handling, ensuring that blend files are only
opened once. Otherwise it would be harder to handle things like dependency
diamonds (libraries that are referenced via multiple paths through multiple
other libraries).
2018-03-07 17:13:47 +01:00
Sybren A. Stüvel
71dd5bc11b Path rewriting when packing.
Doesn't work with sequences, nor with split dirname/basename fields.
2018-03-06 16:06:36 +01:00
Sybren A. Stüvel
8009ff1e47 Added block expansion
The expansion process follows pointers and library links to construct
the full set of actually-used data blocks. This set consists of all data
blocks in the initial blend file, and all *actually linked-to* data
blocks in linked blend files.

I've also removed non-recursive dependency listing.
2018-03-02 15:44:07 +01:00
Sybren A. Stüvel
7167d51730 Added BlendFileBlock.id_name property
Evaluated only once, so safe to call multiple times without producing
excessive disk I/O. Returns None instead of raising KeyError when there is
no (b'id', b'name') field.
2018-03-02 11:26:02 +01:00
Sybren A. Stüvel
f46e761f09 Removed base_index parameter in favour of explicit array handling
The `base_index` parameter is confusing and only works in a limited number
of cases. Having explicit functions to deal with those cases is preferred.
2018-03-01 12:50:22 +01:00
Sybren A. Stüvel
86af05e823 Added recursion into library blend files. 2018-02-28 12:42:27 +01:00
Sybren A. Stüvel
a5bc52523d Some more comments 2018-02-28 11:16:58 +01:00
Sybren A. Stüvel
65b690e998 Added block walker implementations + tests 2018-02-27 17:30:28 +01:00
Sybren A. Stüvel
59c0b6df4c Allow block.get() to return the dna.Field
This is needed by the upcoming dependency tracer.
2018-02-26 18:15:14 +01:00
Sybren A. Stüvel
a56e985cdc Unify behaviour of block[path] and block.get(path) 2018-02-26 18:14:23 +01:00
Sybren A. Stüvel
127f357e49 Marked set() as ported 2018-02-23 15:54:13 +01:00
Sybren A. Stüvel
bce5f4b670 Ported get_file_offset() and renamed to abs_offset() 2018-02-23 15:53:26 +01:00
Sybren A. Stüvel
aed1827ff7 Moved pad_up_4() to inner function as it's only used there. 2018-02-23 15:44:57 +01:00
Sybren A. Stüvel
55075c09b6 Ported get_data_hash() and renamed to hash() 2018-02-23 15:42:48 +01:00
Sybren A. Stüvel
9750a91571 Fixed file leak when opening corrupted file. 2018-02-23 14:26:57 +01:00
Sybren A. Stüvel
eb8281ea82 Fix leaking file object when loading non-blend file 2018-02-23 14:26:57 +01:00
Sybren A. Stüvel
8e0b135eb3 Fixed recompressing after modification 2018-02-23 14:26:57 +01:00
Sybren A. Stüvel
67751d9a3e Fixed loading compressed files 2018-02-23 14:26:57 +01:00
Sybren A. Stüvel
b42a090f32 Support for modifying string/bytes fields. 2018-02-23 14:26:57 +01:00