Boost python hooks

Hello, I’m considering taking some of our more time consuming stage manipulation functionality currently in Python and making a C++ library with boost python hooks. I was wondering if anyone can point me to some resources or examples?

There are several examples on how to do it for an asset resolver, but I haven’t seen anything for a regular library.

The C++ code is very easy and straightforward for me but Boost isn’t my strong point

We use CMake so examples that include CMake files are most appreciated.

Thank you.

Hi @silviapalara ! Maybe have a look at utils.h/wrapUtils.cpp in usdviewq. We made a wrapper class, but really it’s just a few utility functions. usdUtils/wrapIntrospection.cpp also has examples of truly free functions being wrapped out, as part of a larger module.

Thank you, I did look at usdUtils and usdviewq but the CMake situation is a nightmare. Specifically I can’t get the part that creates the python library to work. The build of individual libraries is very tightly woven with the build of the whole of USD and I can’t pick out just what I need. After spending several days in that CMake jungle I was hoping for a simpler example.

@silviapalara, I find the examples from Wētā to be interesting and helpful. I wonder if any of these might provide some pointers to guide you?

Thank you very much for the link Nick, I was able to build and try the examples successfully! That should be enough to point me in the right direction with my work. Thank you so much for the help, so appreciated!

Maybe this will be useful for others in the future so I’m going to post what seems to be close to the bare minimum code and CMake file to do this:

file hello_ext.cpp

#include <boost/python.hpp>
#include "pxr/base/tf/type.h"
#include "pxr/usd/usd/prim.h"
#include "pxr/usd/usdGeom/pointBased.h"

#include <vector>
#include <iostream>

using namespace pxr;
using namespace std;

void scale_by(const UsdPrim &prim, float scale) {
    // Functionality goes here
}

BOOST_PYTHON_MODULE(hello_ext)
{
  using namespace boost::python;
  def("scale_by", scale_by, args("prim"), args("scale"));
}

File CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

set(definition "NOMINMAX")
list(APPEND _PXR_CXX_DEFINITIONS "-D${definition}")
set(_PXR_CXX_DEFINITIONS ${_PXR_CXX_DEFINITIONS} PARENT_SCOPE)
add_definitions(${_PXR_CXX_DEFINITIONS})

set(CMAKE_STATIC_MODULE_PREFIX "lib")

# Assume we already set a var or env var USD_ROOT
set(USD_INCLUDE_DIRS ${USD_ROOT}/include)
set(USD_LIB_DIR ${USD_ROOT}/lib)
set(USD_LIBRARIES
    ${USD_LIB_DIR}/tbb.lib
    ${USD_LIB_DIR}/usd_gf.lib
    ${USD_LIB_DIR}/usd_tf.lib
    ${USD_LIB_DIR}/usd_vt.lib
    ${USD_LIB_DIR}/usd_sdf.lib
    ${USD_LIB_DIR}/usd_usd.lib
    ${USD_LIB_DIR}/usd_usdgeom.lib
)

# Assume we already set a var or env var PYTHON_ROOT
# Replace lib name according to your version of Python
set(PYTHON_LIBRARIES "python39.lib")
set(PYTHON_INCLUDE_DIRS "${PYTHON_ROOT}/include")

# Replace lib name and include dir according to your version of USD
set(Boost_LIBRARIES "${USD_LIB_DIR}/boost_python39-vc142-mt-x64-1_70.lib")
set(Boost_INCLUDE_DIRS "${USD_INCLUDE_DIRS}/boost-1_70")
set(BOOST_PYTHON_NO_LIB True)

# Build libraries without suffix "lib"
set(CMAKE_SHARED_MODULE_PREFIX "")

# Add a shared module
add_library(hello_ext MODULE hello_ext.cpp)

target_link_directories(hello_ext 
    PRIVATE
        "${PYHON_ROOT}/libs"
        ${USD_LIB_DIR}
)
target_include_directories(hello_ext 
    PRIVATE 
        ${PYTHON_INCLUDE_DIRS} 
        ${Boost_INCLUDE_DIRS}
        ${USD_INCLUDE_DIRS}
)
target_link_libraries(hello_ext ${USD_LIBRARIES})

# Copy the .so or .dll into a .pyd so Python can use it
add_custom_command(TARGET hello_ext POST_BUILD 
  COMMAND "${CMAKE_COMMAND}" -E copy 
    ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>/hello_ext.dll
    ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>/hello_ext.pyd
)

From python I used it by doing the following:

import os, sys
# Replace these paths with your Python and USD paths and with the location of your .pyd file
os.add_dll_directory(r'C:/usd/usd-py39/22.03.1/usd/lib')
os.add_dll_directory(r'C:/Users/silvia/work/test/build/Release')

sys.path.insert(0, r'C:/usd/usd-py39/22.03.1/usd/lib/python')
sys.path.insert(0, r'C:/Users/silvia/work/test/build/Release')

from pxr import Usd, UsdGeom
from hello_ext import scale_by

This worked for me in Windows. I’m sure people who know more than me could cut it down even more.