Skip to content

Commit 0004638

Browse files
author
Alex Fuller
committed
IECore{Python}|{VDB} : Added boost::python and nanobind conversion. Python bindings renamed from pyopenvdb to openvdb in later versions
1 parent 0b88aa4 commit 0004638

File tree

5 files changed

+143
-6
lines changed

5 files changed

+143
-6
lines changed

Changes

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
11
10.5.x.x (relative to 10.5.13.0)
22
========
33

4+
Features
5+
--------
6+
7+
- NanoBindConverter : Added new class providing interoperability between Boost Python bindings and NanoBind bindings.
8+
9+
Improvements
10+
------------
411

12+
- IEcoreVDB : Support for the renamed python module `openvdb` in more recent versions of OpenVDB.
13+
14+
Build
15+
-----
16+
17+
- SConstruct :
18+
- Added `NANOBIND_INCLUDE_PATH` option.
519

620
10.5.13.0 (relative to 10.5.12.0)
721
=========

SConstruct

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,12 @@ o.Add(
570570
"",
571571
)
572572

573+
o.Add(
574+
"NANOBIND_INCLUDE_PATH",
575+
"The path to the nanobind include directory.",
576+
"",
577+
)
578+
573579
# Build options
574580

575581
o.Add(
@@ -2069,10 +2075,15 @@ vdbEnvPrepends = {
20692075
"LIBS" : ["openvdb$VDB_LIB_SUFFIX"],
20702076
"CXXFLAGS" : [
20712077
systemIncludeArgument, "$VDB_INCLUDE_PATH",
2072-
systemIncludeArgument, "$PYBIND11_INCLUDE_PATH",
20732078
]
20742079
}
20752080

2081+
if env[ "PYBIND11_INCLUDE_PATH" ] != "" :
2082+
vdbEnvPrepends["CXXFLAGS"].append( [ systemIncludeArgument, "$PYBIND11_INCLUDE_PATH" ] )
2083+
2084+
if env[ "NANOBIND_INCLUDE_PATH" ] != "" :
2085+
vdbEnvPrepends["CXXFLAGS"].append( [ systemIncludeArgument, "$NANOBIND_INCLUDE_PATH" ] )
2086+
20762087
vdbEnv.Prepend( **vdbEnvPrepends)
20772088

20782089
vdbPythonModuleEnv = corePythonModuleEnv.Clone( **vdbEnvSets )
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
2+
//////////////////////////////////////////////////////////////////////////
3+
//
4+
// Copyright (c) 2025, Alex Fuller. All rights reserved.
5+
// Copyright (c) 2024, Cinesite VFX Ltd. All rights reserved.
6+
//
7+
// Redistribution and use in source and binary forms, with or without
8+
// modification, are permitted provided that the following conditions are
9+
// met:
10+
//
11+
// * Redistributions of source code must retain the above
12+
// copyright notice, this list of conditions and the following
13+
// disclaimer.
14+
//
15+
// * Redistributions in binary form must reproduce the above
16+
// copyright notice, this list of conditions and the following
17+
// disclaimer in the documentation and/or other materials provided with
18+
// the distribution.
19+
//
20+
// * Neither the name of John Haddon nor the names of
21+
// any other contributors to this software may be used to endorse or
22+
// promote products derived from this software without specific prior
23+
// written permission.
24+
//
25+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
26+
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29+
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30+
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36+
//
37+
//////////////////////////////////////////////////////////////////////////
38+
39+
#ifndef IECOREPYTHON_NANOBINDCONVERTER_H
40+
#define IECOREPYTHON_NANOBINDCONVERTER_H
41+
42+
#include "boost/python.hpp"
43+
44+
#include "nanobind/nanobind.h"
45+
46+
namespace IECorePython
47+
{
48+
49+
// Registers `boost::python` converters for types
50+
// wrapped using nanobind.
51+
template<typename T>
52+
struct NanoBindConverter
53+
{
54+
55+
static void registerConverters()
56+
{
57+
boost::python::to_python_converter<T, ToNanoBind>();
58+
boost::python::converter::registry::push_back(
59+
&FromNanoBind::convertible,
60+
&FromNanoBind::construct,
61+
boost::python::type_id<T>()
62+
);
63+
}
64+
65+
private :
66+
67+
struct ToNanoBind
68+
{
69+
static PyObject *convert( const T &t )
70+
{
71+
nanobind::object o = nanobind::cast( t );
72+
Py_INCREF( o.ptr() );
73+
return o.ptr();
74+
}
75+
};
76+
77+
struct FromNanoBind
78+
{
79+
80+
static void *convertible( PyObject *object )
81+
{
82+
nanobind::handle handle( object );
83+
return handle.cast<T>() ? object : nullptr; // NOT WORKING, NOR .can_cast<T>() | see: https://nanobind.readthedocs.io/en/latest/porting.html#type-casters
84+
}
85+
86+
static void construct( PyObject *object, boost::python::converter::rvalue_from_python_stage1_data *data )
87+
{
88+
void *storage = ( ( boost::python::converter::rvalue_from_python_storage<T> * ) data )->storage.bytes;
89+
T *t = new( storage ) T;
90+
data->convertible = storage;
91+
92+
nanobind::handle handle( object );
93+
*t = handle.cast<T>(); // NOT WORKING, NOR .from_cpp<T>() | see: https://nanobind.readthedocs.io/en/latest/porting.html#type-casters
94+
}
95+
96+
};
97+
98+
};
99+
100+
} // namespace IECorePython
101+
102+
#endif // IECOREPYTHON_NANOBINDCONVERTER_H
103+

python/IECoreVDB/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@
4141
# we use the warnings module to suppress these during the import
4242
with warnings.catch_warnings():
4343
warnings.simplefilter("ignore")
44-
import pyopenvdb
44+
try:
45+
import pyopenvdb
46+
except:
47+
import openvdb
4548

4649
from ._IECoreVDB import *
4750

src/IECoreVDB/bindings/IECoreVDBModule.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,19 @@
4444
// OpenVDB 10.0 and earlier used `boost::python` for its Python bindings, but
4545
// this was switched to PyBind11 in OpenVDB 10.1. We need to take a different
4646
// approach to binding VDBObject's grid accessors in each case.
47-
#if OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER > 10 || OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER == 10 && OPENVDB_LIBRARY_MINOR_VERSION_NUMBER >= 1
47+
// For OpenVDB 12 they yet again changed bindings to nanobind instead.
48+
#if OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER == 11 || OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER == 10 && OPENVDB_LIBRARY_MINOR_VERSION_NUMBER >= 1
4849
#include "IECorePython/PyBindConverter.h"
4950
#define IECOREVDB_USE_PYBIND
51+
#elif OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER > 11
52+
#include "IECorePython/NanoBindConverter.h"
53+
#define IECOREVDB_USE_NANOBIND
5054
#endif
5155

5256
using namespace boost::python;
5357
using namespace IECoreVDB;
5458

55-
#ifndef IECOREVDB_USE_PYBIND
59+
#if !defined( IECOREVDB_USE_PYBIND ) && !defined( IECOREVDB_USE_NANOBIND )
5660

5761
namespace
5862
{
@@ -148,7 +152,7 @@ void insertGrid( VDBObject::Ptr vdbObject, boost::python::object pyObject )
148152

149153
} // namespace
150154

151-
#endif // #ifndef IECOREVDB_USE_PYBIND
155+
#endif // #if !defined( IECOREVDB_USE_PYBIND ) && !defined( IECOREVDB_USE_NANOBIND )
152156

153157
namespace
154158
{
@@ -171,6 +175,8 @@ BOOST_PYTHON_MODULE( _IECoreVDB )
171175

172176
#ifdef IECOREVDB_USE_PYBIND
173177
IECorePython::PyBindConverter<openvdb::GridBase::Ptr>::registerConverters();
178+
#elif IECOREVDB_USE_NANOBIND
179+
IECorePython::NanoBindConverter<openvdb::GridBase::Ptr>::registerConverters();
174180
#endif
175181

176182
IECorePython::RunTimeTypedClass<VDBObject>()
@@ -179,7 +185,7 @@ BOOST_PYTHON_MODULE( _IECoreVDB )
179185
.def("gridNames", &::gridNames)
180186
.def("metadata", &VDBObject::metadata)
181187
.def("removeGrid", &VDBObject::removeGrid)
182-
#ifdef IECOREVDB_USE_PYBIND
188+
#if defined( IECOREVDB_USE_PYBIND ) || defined( IECOREVDB_USE_NANOBIND )
183189
.def( "findGrid", (openvdb::GridBase::Ptr (VDBObject::*)( const std::string &name ))&VDBObject::findGrid )
184190
.def( "insertGrid", &VDBObject::insertGrid )
185191
#else

0 commit comments

Comments
 (0)