Skip to content

Commit

Permalink
Add nanobind Python bindings
Browse files Browse the repository at this point in the history
Signed-off-by: Max Lantas <mnxndev@outlook.com>
  • Loading branch information
mnxn committed Sep 26, 2024
1 parent 07ba86f commit ebffce5
Show file tree
Hide file tree
Showing 9 changed files with 459 additions and 1 deletion.
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ if (PYBIND11)
add_subdirectory(src/pybind11)
endif()

option(NANOBIND "Set ON to compile nanobind PyImath bindings")
if (NANOBIND)
add_subdirectory(src/nanobind)
endif()

option(BUILD_WEBSITE "Set ON to build the readthedocs website source")
if (BUILD_WEBSITE AND NOT IMATH_IS_SUBPROJECT)
add_subdirectory(website)
Expand Down Expand Up @@ -119,4 +124,3 @@ endif()
if(NOT IMATH_IS_SUBPROJECT)
include(cmake/clang-format.cmake)
endif()

17 changes: 17 additions & 0 deletions src/nanobind/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.

set(NANOBINDIMATH_OVERRIDE_PYTHON_INSTALL_DIR "" CACHE STRING "Override the install location for imath.so and imathnumpy.so modules")

########################
## Build related options

# Suffix to append to root name, this helps with version management
# but can be turned off if you don't care, or otherwise customized
#
set(NANOBINDIMATH_LIB_SUFFIX "-${IMATH_VERSION_API}" CACHE STRING "String added to the end of all the libraries")
# This provides a root for the unique name of the library based on
# the version of python being compiled for
set(NANOBINDIMATH_LIB_PYTHONVER_ROOT "_Python" CACHE STRING "String added as a root to the identifier of the python version in the libraries")

add_subdirectory(NanobindImath)
109 changes: 109 additions & 0 deletions src/nanobind/NanobindImath/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.

find_package(Python REQUIRED COMPONENTS Interpreter Development)
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
find_package(nanobind REQUIRED)

#
# Source/headers
#

set(NANOBINDIMATH_SOURCES
NanobindImathBox.cpp
NanobindImathVec.cpp
)

set(NANOBINDIMATH_HEADERS
NanobindImathExport.h
NanobindImath.h
)

#
# shared library, e.g. libNanobindImath_Python3_11-3_2.so.30.3.2.0
#

set(NANOBINDIMATH_LIBRARY NanobindImath)

add_library(${NANOBINDIMATH_LIBRARY} SHARED ${NANOBINDIMATH_SOURCES})

nanobind_build_library(nanobind-static)

target_link_libraries(${NANOBINDIMATH_LIBRARY} PRIVATE Imath::Imath nanobind-static)

# Set include directories
target_include_directories(${NANOBINDIMATH_LIBRARY} PRIVATE ${Python3_INCLUDE_DIRS} ${Imath_INCLUDE_DIRS})

if(NOT "${NANOBINDIMATH_LIB_PYTHONVER_ROOT}" STREQUAL "")
set(pythonver_root "${NANOBINDIMATH_LIB_PYTHONVER_ROOT}${Python3_VERSION_MAJOR}_${Python3_VERSION_MINOR}")
message("pythonver_root ${NANOBINDIMATH_LIB_PYTHONVER_ROOT}${Python3_VERSION_MAJOR}_${Python3_VERSION_MINOR}")
endif()

if(BUILD_SHARED_LIBS)
# This creates the so-versioned library symlinks
set_target_properties(${NANOBINDIMATH_LIBRARY} PROPERTIES
SOVERSION ${IMATH_LIB_SOVERSION}
VERSION ${IMATH_LIB_VERSION}
OUTPUT_NAME "${NANOBINDIMATH_CURLIB_OUTROOT}${NANOBINDIMATH_LIBRARY}${pythonver_root}${NANOBINDIMATH_LIB_SUFFIX}"
)
endif()

#
# python module, e.g. nanobindimath.cpython-311-x86_64-linux-gnu.so
#

set(NANOBINDIMATH_MODULE nanobindimath)

nanobind_add_module(nanobindimath MODULE nanobindimathmodule.cpp $<TARGET_OBJECTS:${NANOBINDIMATH_LIBRARY}>)

target_link_libraries(${NANOBINDIMATH_MODULE} PRIVATE Imath::Imath)

if(SKBUILD)
set(PYTHON_INSTALL_DIR ${SKBUILD_PLATLIB_DIR})
else()
set(PYTHON_INSTALL_DIR "lib/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages")
endif()

if (IMATH_INSTALL)

# module

install(TARGETS ${NANOBINDIMATH_MODULE} DESTINATION ${PYTHON_INSTALL_DIR} COMPONENT python)

# shared library

install(TARGETS ${NANOBINDIMATH_LIBRARY}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

if(BUILD_SHARED_LIBS AND (NOT "${IMATH_LIB_SUFFIX}" STREQUAL "") AND IMATH_INSTALL_SYM_LINK)

# create symlinks for the shared object so versions

string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
set(verlibname ${CMAKE_SHARED_LIBRARY_PREFIX}${NANOBINDIMATH_LIBRARY}${pythonver_root}${IMATH_LIB_SUFFIX}${CMAKE_${uppercase_CMAKE_BUILD_TYPE}_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX})
set(baselibname ${CMAKE_SHARED_LIBRARY_PREFIX}${NANOBINDIMATH_LIBRARY}${pythonver_root}${CMAKE_${uppercase_CMAKE_BUILD_TYPE}_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX})
file(CREATE_LINK ${verlibname} ${CMAKE_CURRENT_BINARY_DIR}/${baselibname} SYMBOLIC)
if(WIN32)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${baselibname} DESTINATION ${CMAKE_INSTALL_FULL_BINDIR})
install(CODE "message(STATUS \"Creating symlink ${CMAKE_INSTALL_FULL_BINDIR}/${baselibname} -> ${verlibname}\")")
else()
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${baselibname} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
install(CODE "message(STATUS \"Creating symlink ${CMAKE_INSTALL_FULL_LIBDIR}/${baselibname} -> ${verlibname}\")")
endif()
endif()

# pkgconfig

set(pcinfile NanobindImath.pc.in)
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix "\${prefix}")
set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
string(REPLACE ".in" "" pcout ${pcinfile})
configure_file(${pcinfile} ${CMAKE_CURRENT_BINARY_DIR}/${pcout} @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${pcout} DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)

endif()
22 changes: 22 additions & 0 deletions src/nanobind/NanobindImath/NanobindImath.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenEXR Project.
//

// clang-format off

#include <nanobind/nanobind.h>
#include <nanobind/operators.h>
#include "NanobindImathExport.h"

#ifndef _NanobindImath_h_
#define _NanobindImath_h_

namespace NanobindImath {

NANOBINDIMATH_EXPORT void register_imath_vec(nanobind::module_& m);
NANOBINDIMATH_EXPORT void register_imath_box(nanobind::module_& m);

}

#endif
17 changes: 17 additions & 0 deletions src/nanobind/NanobindImath/NanobindImath.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
##
## SPDX-License-Identifier: BSD-3-Clause
## Copyright Contributors to the OpenEXR Project.
##

prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
pythonver=@pythonver_root@

Name: NanobindImath
Description: nanobind-based python bindings for the Imath libraries
Version: @IMATH_VERSION@
Libs: -L${libdir} -lImath${libsuffix} -lNanobindImath${pythonver$}${libsuffix}

Cflags: -I${includedir} -I${includedir}/Imath
60 changes: 60 additions & 0 deletions src/nanobind/NanobindImath/NanobindImathBox.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenEXR Project.
//

#include "NanobindImath.h"
#include <ImathBox.h>

namespace NanobindImath {

template <class T, class V>
void register_box(nanobind::class_<T>& c)
{
c.def(nanobind::init<>())
.def(nanobind::init<const V &>())
.def(nanobind::init<const V &, const V &>())
.def(nanobind::self == nanobind::self)
.def(nanobind::self != nanobind::self)
.def("makeEmpty", &T::makeEmpty, "makeEmpty() make the box empty")
.def("makeInfinite", &T::makeInfinite, "makeInfinite() make the box cover all space")
.def_rw("min", &T::min)
.def_rw("max", &T::max)
.def("extendBy", nanobind::overload_cast<const T &>(&T::extendBy), "extendBy(point) extend the box by a box")
.def("extendBy", nanobind::overload_cast<const V &>(&T::extendBy), "extendBy(point) extend the box by a point")
.def("size", &T::size, "size() size of the box")
.def("center", &T::center, "center() center of the box")
.def("intersects",nanobind::overload_cast<const V &>(&T::extendBy), "intersects(point) returns true if the box intersects the given point")
.def("intersects",nanobind::overload_cast<const T &>(&T::extendBy), "intersects(box) returns true if the box intersects the given box")
.def("majorAxis",&T::majorAxis, "majorAxis() major axis of the box")
.def("isEmpty",&T::isEmpty, "isEmpty() returns true if the box is empty")
.def("isInfinite",&T::isInfinite, "isInfinite() returns true if the box covers all space")
.def("hasVolume",&T::hasVolume, "hasVolume() returns true if the box has volume");

}

template <class T, class V>
void register_box2(nanobind::module_& m, const char * name)
{
nanobind::class_<T> c(m, name);
register_box<T, V>(c);
}

template <class T, class V>
void register_box3(nanobind::module_& m, const char * name)
{
nanobind::class_<T> c(m, name);
register_box<T, V>(c);
}

void register_imath_box(nanobind::module_& m)
{
register_box2<Imath::Box2d, Imath::V2d>(m, "Box2d");
register_box2<Imath::Box2f, Imath::V2f>(m, "Box2f");

register_box3<Imath::Box3d, Imath::V3d>(m, "Box3d");
register_box3<Imath::Box3f, Imath::V3f>(m, "Box3f");

}

}
28 changes: 28 additions & 0 deletions src/nanobind/NanobindImath/NanobindImathExport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenEXR Project.
//

// clang-format off

#ifndef NANOBINDIMATHEXPORT_H
#define NANOBINDIMATHEXPORT_H

#if defined(IMATH_DLL)
#if defined(PLATFORM_VISIBILITY_AVAILABLE)
#define NANOBINDIMATH_EXPORT __attribute__((visibility("default")))
#define NANOBINDIMATH_EXPORT __attribute__((visibility("default")))
#elif defined(_MSC_VER)
#if defined(NANOBINDIMATH_BUILD)
#define NANOBINDIMATH_EXPORT __declspec(dllexport)
#else
#define NANOBINDIMATH_EXPORT __declspec(dllimport)
#endif
#else
#define NANOBINDIMATH_EXPORT
#endif
#else
#define NANOBINDIMATH_EXPORT
#endif

#endif // #ifndef NANOBINDIMATHEXPORT_H
Loading

0 comments on commit ebffce5

Please sign in to comment.