Hello USD - Part 5: Python setup pt 2, what really works

The post assumes some familiarity with yesterdays post

To skip to the write up of what works go to: https://github.com/carlynorama/USDHelloWorld/blob/main/SETUP.md

The last hold out

Pixar includes a viewer utility in with their USD python tools. It’s why to include PyOPenGL and PySide6 (Qt, cross platform UI tool).

usdview takes one parameter, the name of a file like below.

usdview HelloWorld.usda 

I didn’t have a single build that could run it without errors or crashing. The first time I ran that command using my pyenv 3.7.9 build I got the following error message

State file not found, a new one will be created.
Traceback (most recent call last):
  File "/Users/$USER/opb/USDefault379/bin/usdview", line 35, in <module>
    Usdviewq.Launcher().Run()
  File "/Users/$USER/opb/USDefault379/lib/python/pxr/Usdviewq/__init__.py", line 86, in Run
    self.__LaunchProcess(arg_parse_result)
  File "/Users/$USER/opb/USDefault379/lib/python/pxr/Usdviewq/__init__.py", line 396, in __LaunchProcess
    (app, appController) = self.LaunchPreamble(arg_parse_result)
  File "/Users/$USER/opb/USDefault379/lib/python/pxr/Usdviewq/__init__.py", line 386, in LaunchPreamble
    appController = AppController(arg_parse_result, contextCreator)
  File "/Users/$USER/opb/USDefault379/lib/python/pxr/Usdviewq/appController.py", line 410, in __init__
    self._dataModel = UsdviewDataModel(self._makeTimer, self._configManager.settings)
  File "/Users/$USER/opb/USDefault379/lib/python/pxr/Usdviewq/appController.py", line 128, in __init__
    self._viewSettingsDataModel = ViewSettingsDataModel(self, settings)
  File "/Users/$USER/opb/USDefault379/lib/python/pxr/Usdviewq/viewSettingsDataModel.py", line 136, in __init__
    QtCore.QObject.__init__(self)
TypeError: __init__() missing 2 required positional arguments: 'parent' and 'name'

At this point I’d been having enough trouble that I was probably missing obvious things and should go get help: https://github.com/PixarAnimationStudios/OpenUSD/issues/2520

I learned that pip3 install PySide6==6.4.3 would have been a better choice for my set up.

Honestly if I’d had actually scrolled down the install versions page and used those recommended versions, that would have been smart!

Reinstalling PySide and recompiling got usdview to open!!! YAY!! but only briefly before it crashed, unable to find OpenGL.

I did try a trick mentioned on a different GitHub issue

pip3 install PyOpenGL PyOpenGL_accelerate

Which strangely got my pyenv 3.7.9 build usdview to behave the same as my system install of 3.7.9’s usdview- Where it opens and DOESN’T crash, but also doesn’t render, and still complains it can’t find OpenGL, printing out an error message .

Mystery Solved

The folks part of Academy Software Foundation USD working group slack rock.

From them I learned Apple changed how frameworks were stored between macOS 10 and macOS 11. Python 3.9 has the patch. If I really really read the version page, they do in fact indicate they were using MacOS 10.

Switching my pyenv to 3.9 made everything work perfectly as far as I can tell.

Screenshot of the USDView interface displaying the hello world sphere. It also displaces the usd tree and other information about the stage such as the World Bounding Box, and materials that the USD is using. In this case none. There is a search box for a property name as well.

SUCCESS.

Trouble shooting Dynamic Library Paths

To be honest, when I first looked at the output of the OpenGL error I assumed it was just assuring me it was traversing my $PATH. As list of places to look for binaries, I admit I thought was a weird for that to be used to go looking for OpenGL, a system Framework. But once the Framework handling change was mentioned, I realized that of course it wasn’t my PATH, it was the LD_LIBRARY_PATH, which is the essentially the $PATH but for the system to find the shared libraries that compiled binaries depend on. In the future, a reminder that it is always helpful to run the below when working with unfamiliar projects.

# when you know the full path example
otool -L $BUILD_FOLDER/bin/usdcat
# for pulling out the path of a binary in the $PATH example
otool -L `which python3`

From man otool about the option -L: “Display the names and version numbers of the shared libraries that the object file uses, as well as the shared library ID if the file is a shared library.” On Apple platforms these can also be called “dynamic libraries”.

What displays at the beginning of each list entry is the path the system looks for the library in. If it doesn’t have an @ at the beginning of that path it’s hard coded, and if your system doesn’t have it you’re almost out of luck. Don’t panic if they aren’t all @, /System/Library links and /usr/lib links frequently work out if you are targeting machines running the same OS as the one you build on. But that doesn’t always stay true over time, e.g. the need to do a system install of Python 3.7.9 for USDZ Tools.

To dig further in to the @’s, i.e. the dynamic libraries, use -l (“Display the load commands.”) which includes further descriptions.

## when you know the full path example
otool -l $BUILD_FOLDER/bin/usdcat
## for pulling out the path of a binary in the $PATH example
otool -l `which python3`
## Limit the search
otool -l $BUILD_FOLDER/bin/usdcat | grep RPATH -A2
## if usdcat is in path already
otool -l `which usdcat` | grep RPATH -A2

In the results will be the tree of places the linker will look. For usdcat, where the results say @loader_path, it would be the equivalent of $BUILD_FOLDER/bin/, i.e. the place where the binary being inspected lives.

But what if binaries throw an error related to one of these paths?

Run man dyld, the list at the top are all the variables one can theoretically change about where a the computer will look for a dynamic library. Unless very very very sure, don’t mess with this. In fact, System Integrity Protection will stop/ignore changes. It’s that bad. With SIP disabled, one CAN update these paths like $PATH, but wow, that’s a commitment, and a sign to look for another way. I’m not even going to show how, because it’s that bad of an idea unless it’s like a single board computer dedicated to a single cause and there is no other way because the clock is ticking and you’re in the field… anyway you get the drill.

I’m glad there was another way.

Apple’s USDZ Tools

The framework change issue made me question if the Apple compiled USDZ Tools that REQUIRE 3.7.9 are really working on my setup as well as I thought they were. All in all, not perfect but a lot does work. This is on my macOS 11 box, so it’s possible results would be different on one running macOS 13.4.

Test results:

USD folder

samples

Boost errors never come as a true surprise because it’s everywhere. Boost is like a crazy Standard Library for C++, which I think you’ll find not so “Standard” anymore. (Insert Prince Humperdinck meme)

usdzconvert

Feedback No: FB12499226

All in all I feel in good shape to enjoy the holiday without dangling threads in regards to OpenUSD builds.

Back in a few.