Page MenuHome

[Blender Asset Tracer] External files with the same name (and path) but which live on different drives are packed as a single file
Closed, ResolvedPublic

Description

Blender Asset Tracer (BAT) runs into problems when packing a blender file which references two or more files with the same file name and path but which exist on different drives.
The different files get combined into a single file when packed into the _outside_project folder that all external assets get bundled into when packing.

I have attached an image of a scene before and after being packed by BAT. You should see that one of the cube has it's texture change.

To reproduce this issue:

  1. Save two different textures to different drives but use the same file name and path (example: C:\test1.jpg and E:\test1.jpg or C:\test\test1.jpg and E:\test\test1.jpg)
  2. Reference these textures in a .blend file in some way (add them as material textures) and save the scene
  3. Use BAT to pack the blender file from command line or as a module import
  4. open up the target directory and inside the _outside_project directory you should see that all assets with the same names have been merged

I believe that this is likely to be a Windows issue since it's the drive letters that seem to be causing the issue.

Event Timeline

Oliver Dawes (haiku) triaged this task as Waiting for Developer to Reproduce priority.
Brecht Van Lommel (brecht) raised the priority of this task from Waiting for Developer to Reproduce to Needs Triage by Developer.

A potential change which fixes this issue for me is to change the _find_new_paths() method in pack/__init__.py from:

def _find_new_paths(self):
     """Find new locations in the BAT Pack for the given assets."""

     for path in self._new_location_paths:
         act = self._actions[path]
         assert isinstance(act, AssetAction)
         # Like a join, but ignoring the fact that 'path' is absolute.
         act.new_path = pathlib.Path(self._target_path, '_outside_project', *path.parts[1:])

to:

def _find_new_paths(self):
    """Find new locations in the BAT Pack for the given assets."""

    for path in self._new_location_paths:
        act = self._actions[path]
        assert isinstance(act, AssetAction)

        # get the path but ignore the fact that the 'path' is absolute
        path_parts = list(path.parts[1:])

        # on windows take the assets drive into account otherwise two assets with the same name on different drives
        # will overwrite each other
        drive = path.drive
        if len(path.drive) > 0:
            # get the drive letter and ignore the ':' that comes after it
            drive_letter = drive[0]
            path_parts.insert(0, drive_letter)

        act.new_path = pathlib.Path(self._target_path, '_outside_project', *path_parts)

Note: I have only tested this on Windows

Nice find, thanks for posting a solution in code.

I tweaked the code a bit and committed as 113b0c9bb8607472be8232d0f806b28fa232d399.