Quick Answer:
You can use the python scripting tools to remove filepaths with a single button press. The script below will add a button to the topbar in File > Clean Up > Clear Filepaths to replace all filepaths in the file with the letter b
.
import bpy
from bpy.utils import register_class, unregister_class
bl_info = {
"name" : "Clear Blender Filepaths",
"location" : "Top toolbar > File > Clean Up > Clear Blender Filepaths",
"description" : 'Removes personal filepaths from your blender file',
"blender" : (3, 6, 2),
"category" : "System",
}
class cbf(bpy.types.Operator):
bl_label = "Clear Filepaths"
bl_idname = "cbf.cleanblenderfilepaths"
bl_description = '''Save an uncompressed copy of your .blend file with personal filepaths cleared like
"C:\\Users\\my username\\Embarassing folder name\\", and
"D:\\Personal stuff\\Oh shoot I can\'t believe this was saved to that blend file I put on Gumroad\\"'''
def execute(self, context):
#don't run if the file has not been saved yet
if not bpy.data.filepath:
return {'FINISHED'}
#save the file as an uncompressed file next to the original
bpy.ops.wm.save_as_mainfile(filepath = bpy.data.filepath.replace('.blend', '_cleaned.blend'), compress = False, relative_remap = False)
#collect all filepaths
filepath_list = []
def add(this):
if this and (this not in filepath_list):
filepath_list.append(this)
for cat in [bpy.data.images,
bpy.data.objects,
bpy.data.linestyles,
bpy.data.materials,
bpy.data.node_groups,
bpy.data.texts,
bpy.data.cameras,
bpy.data.lights,
bpy.data.meshes]:
for item in cat:
for check in ['filepath', 'filepath_raw']:
if getattr(item, check, None):
add(getattr(item, check, None))
if getattr(item, 'original', None):
if getattr(item.original, 'filepath', None):
add(item.original.filepath)
if getattr(item, 'library_weak_reference', None):
if getattr(item.library_weak_reference, 'filepath', None):
add(item.library_weak_reference.filepath)
if getattr(item, 'packed_files', None):
for packed_file in getattr(item, 'packed_files', []):
if getattr(packed_file, 'filepath', None):
add(packed_file.filepath)
add(bpy.data.filepath)
add(bpy.context.scene.render.filepath if bpy.context.scene.render.filepath != '/tmp\\' else None)
#read the whole file in and check for any filepath instances
original_filepath = bpy.data.filepath
file = open(original_filepath, 'rb')
raw_data = file.read()
for path in filepath_list:
raw_data = raw_data.replace(path.encode(), b'b'*len(path))
file.close()
#overwrite the file with filepaths replaced as 'bbbbbbb'
file = open(original_filepath, 'wb')
file.write(raw_data)
file.close()
#close blender so the cleaned file is not accidentally overwritten
bpy.ops.wm.quit_blender()
return {'FINISHED'}
def menu_draw(self, context):
self.layout.operator("cbf.cleanblenderfilepaths")
def wrap(register_bool):
register_class(cbf) if register_bool else unregister_class(cbf)
bpy.types.TOPBAR_MT_file_cleanup.append(menu_draw) if register_bool else bpy.types.TOPBAR_MT_file_cleanup.remove(menu_draw)
def register():
wrap(True)
def unregister():
wrap(False)
if __name__ == "__main__":
register()
Longer answer:
Despite being an open source program, there seems to be little information on this topic, and this page has the most info I’ve found on PII in a .blend file so let’s sum up all the info and add some more.
- Editing an uncompressed save file for filepaths is possible if the resources are packed into the blend file, but you need to know exactly what you’re looking for.
- Editing a compressed save file seems to be possible as long as the amount of characters in the filepath remains the same. However, editing a compressed file will lead to the hex editor missing a path due to compression obfuscating some filepath strings. I have manually edited a compressed save file and removed all instances of any relative or absolute filepaths, but I reopened the compressed file in blender and was still able to access the library_weak_reference.filepath attribute that contained one of the directories I just removed in the hex editor.
- Working in a higher up directory will still save those directory names to the blend file, and the blend file can still be “contaminated” if you import or append something from a .blend file located in a personal directory containing your username. Exporting everything to a different format then reimporting works but is not feasible for large projects with many objects that would have to be reimported. All materials would also have to be recreated from scratch (see library_weak_reference issue below, this would apply to appended materials)
- It may have worked in previous versions, but for me, attempting to delete a DATA block containing a personal filepath in a Blender 3.6 save file resulted in blender just loading the default scene. I’m guessing Blender thought the file was corrupt and didn’t attempt to load it.
So in a typical usage scenario it looks like it is unavoidable to have filepaths in the .blend file. How can you know what filepaths are being used in the file? And can you edit them in Blender itself? From what I’ve gathered, there are a few places to look in blender for filepaths using the python api:
- The current file’s directory accessed with bpy.data.filepath (not completely sure if this is saved to the .blend)
- The render output filepath accessed with
bpy.context.scene.render.filepath
- Absolute and Relative directories where images were imported from (accessed with
bpy.data.images[0].filepath
, and bpy.data.images[0].original.filepath)
- Absolute and Relative directories from packed images accessed with
bpy.data.images[0].packed_files[0].filepath
- Filepaths to other .blend files from which objects, meshes, node_groups, materials, etc were appended from (check
bpy.data.objects[-1].library_weak_reference.filepath
after appending an object and it will show you the filepath to the blend file you imported it from)
Filepath variables can be set using Blender’s python api, but library_weak_reference filepaths are read only, so we are forced to edit the file with a hex editor or script to remove all filepaths. That makes the process…
- Pack all files into the blender file
- Save the blender file as uncompressed
- Use the Blender Python api to walk through the bpy.data structure until all filepath instances are found
- Use a hex editor or a script (like the above python script) to clear out all filepaths found in the file with a random string of the same length (like
bbb
)
- Inspect the file with a hex editor to confirm all filepaths have been removed
- Re-open the file in blender and walk through all filepath instances again to ensure all filepaths have been removed
Using this method with what I would consider a typical file (containing multiple mesh objects with multiple materials and dozens of packed images) resulted in no personally identifiable absolute or relative paths showing in a hex editor.