[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

absolute path to a file

Please remember to CC the list.

On 19Aug2019 22:06, Paul St George <email at paulstgeorge.com> wrote:
>On 19/08/2019 14:16, Cameron Simpson wrote:
>>There's a remark on that web page I mentioned that suggests that the 
>>leading '//' indicates the filename is relative to the Blender model, 
>>so the context directory for the '//' is likely 
>Yes. That makes sense. The reason I was testing with two images, one 
>at /Users/Lion/Desktop/test8/image01.tif and the other at 
>/Users/Lion/Desktop/images/image02.tif is that I cannot rely on images 
>being in the same folder as the Blender file.
>So, let's assume the context directory is /Users/Lion/Desktop/test8
>and see how we get on below.
>>realpath needs a UNIX path. Your //image01.tif isn't a UNIX path, it 
>>is a special Blender path. First you need to convert it. By replacing 
>>'//' with the blend file's directory. Then you can call realpath. If 
>>you still need to.
>Understood. Now. Thanks!
>Did you just [...snip...] yourself?

Yes. It keeps the surrounding context manageable. In this way you know 
to which text I am referring, without having to wade through paragraphs 
to guess what may be relevant.

>> ?? from os.path import dirname
>> ?? # Get this from somewhere just hardwiring it for the example.
>> ?? # Maybe from your 'n' object below?
>> ?? blend_file = '/Users/Lion/Desktop/test8/tifftest8.blend'
>Is this setting a relative path?
>> ?? blender_image_file = n.image.filename
>> ?? unix_image_file = unblenderise(blender_image_file, dirname(blend_file))
>>Now you have a UNIX path. If blend_file is an absolute path, 
>>unix_image_path will also be an absolute path. But if blend_file is 
>>a relative path (eg you opened up "tifftest8.blend") unix_image_path 
>>will be a relative path.
>Does unix_image_path = unix_image_file?

Yeah, sorry,  my mistake.

>Two possibilities here.
>blend_file (and so unix_image_file) is an absolute path OR blend_file 
>(and so unix_image_file) is a relative path.
>I just want to check my understanding. If I supply the path to 
>blend_file then it is absolute, and if I ask Python to generate the 
>path to blend_file from within Blender it is relative. Have I got it?

Not quite. What seems to be the situation is:

You've got some object from Blender called "n.image", which has a 
".file" attribute which is a Blender reference to the image file of the 
form "//image01.tif".

I presume that Blender has enough state inside "n" or "n.image" to 
locate this in the real filesystem; maybe it has some link to the 
Blender model of your blend file, and thus knows the path to the blend 
file and since //image01.tif is a reference relative to the blend file, 
it can construct the UNIX path to the file.

You want to know the UNIX pathname to the image file (maybe you want to 
pass it to some unrelated application to view the file or something).

So you need to do what Blender would do if it needs a UNIX path (eg to 
open the file).

The formula for that is dirname(path_to_blendfile) with n.image.file[2:] 
appended to it. So that's what we do with unblenderise(): if the 
filename is a "Blender relative name", rip off the "//" and prepend the 
blend file directory path. That gets you a UNIX path which you can hand 
to any function expecting a normal operating system pathname.

Whether that is an absolute path or a relative path is entirely "does 
the resulting path start with a '/'"?

An absolute path starts with a slash and is relative to the root of the 
filesystem. You can use such a path regardless of what your current 
working directory is, because it doesn't use the working directory.

A relative path doesn't start with a slash and is relative to the 
current working directory. It only works if you're in the right working 

_Because_ a relative path depends on the _your_ working directory, 
usually we pass around absolute paths if we need to tell something else 
about a file, because that will work regardless if what _their_ working 
directory may be.

So, you may well want to turn a relative path into an absolute path...

>If I decided not to supply the path and so ended up with a relative 
>UNIX path, I could now use realpath or abspath to find the absolute 
>path. Have I still got it?

This is correct.

Abspath may even call realpath to do its work, unsure.

>It works very well. So thank you! I tested it with a Blend file that 
>had two images, one in the same folder as the Blend file and the other 
>was in a folder on the Desktop called 'images'.
>The initial results were:
>Plane uses image01.tif saved at //image01.tif which is at 
>Plane uses image02.tif saved at //../images/image02.tif which is at 
>BUT as you say, this was easily sorted by using os.path.realpath or 
>os.path.abspath. Both worked equally well.

Yep. Abspath does some things in a purely lexical way: it resolves '.' 
and '..' components in the path even if they don't exist. For example it 
resolves 'a/b/c/d/../../../../foo' for me even though here 'a/b/c/d' 
doesn't exist: it see the '.. and strips off the preceeding component, 
repeatedly. So it starts with 'foo' after that pahse  and prepends the 
working directory path.

The system realpath is not documented to work if some of the path is 
fictitious, but the Python realpath seems to work even then, maybe it 
falls back to abspath or something.

Abspath takes a relative path and returns you an absolute path with the 
'.' and '..' components stripped out.

Realpath follows symlinks and stuff and returns you the direct absolute 
path _after_ all that - one that doesn't traverse symlinks.

For your purposes the results are equally functional.

>Plane uses image01.tif saved at //image01.tif which is at 
>Plane uses image02.tif saved at //../images/image02.tif which is at 
>So, everything now works. Thank you again. I am just a little unclear 
>on the absolute and relative, hence my questions.

Hope the above xaplinations help.

Cameron Simpson <cs at cskk.id.au>