Skip to content

Commit 6af71fb

Browse files
authored
Merge pull request #1402 from johnhaddon/vdbPyBind
VDBObject bindings : Adapt for OpenVDB 10.1
2 parents d293bc9 + 225d215 commit 6af71fb

File tree

4 files changed

+148
-15
lines changed

4 files changed

+148
-15
lines changed

Changes

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

4+
Features
5+
--------
6+
7+
- PyBindConverter : Added new class providing interoperability between Boost Python bindings and PyBind11 bindings.
8+
49
Improvements
510
------------
611

@@ -10,6 +15,7 @@ Fixes
1015
-----
1116

1217
- CompoundObject : Fixed crashes in Python bindings caused by passing `None` as a key.
18+
- VDBObject : Fixed Python bindings for OpenVDB 10.1.
1319

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

src/IECoreVDB/bindings/IECoreVDBModule.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,19 @@
4141

4242
#include "IECoreVDB/VDBObject.h"
4343

44+
// OpenVDB 10.0 and earlier used `boost::python` for its Python bindings, but
45+
// this was switched to PyBind11 in OpenVDB 10.1. We need to take a different
46+
// 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
48+
#include "IECorePython/PyBindConverter.h"
49+
#define IECOREVDB_USE_PYBIND
50+
#endif
4451

4552
using namespace boost::python;
4653
using namespace IECoreVDB;
4754

55+
#ifndef IECOREVDB_USE_PYBIND
56+
4857
namespace
4958
{
5059

@@ -118,18 +127,6 @@ openvdb::GridBase::Ptr getGridFromPyObject( const boost::python::object &gridObj
118127

119128
} // namespace iepyopenvdb
120129

121-
122-
boost::python::list gridNames( VDBObject::Ptr vdbObject )
123-
{
124-
boost::python::list result;
125-
std::vector<std::string> names = vdbObject->gridNames();
126-
for( const auto &name : names )
127-
{
128-
result.append( name );
129-
}
130-
return result;
131-
}
132-
133130
boost::python::object findGrid( VDBObject::Ptr vdbObject, const std::string &gridName )
134131
{
135132
openvdb::GridBase::Ptr grid = vdbObject->findGrid( gridName );
@@ -151,17 +148,44 @@ void insertGrid( VDBObject::Ptr vdbObject, boost::python::object pyObject )
151148

152149
} // namespace
153150

151+
#endif // #ifndef IECOREVDB_USE_PYBIND
152+
153+
namespace
154+
{
155+
156+
boost::python::list gridNames( VDBObject::Ptr vdbObject )
157+
{
158+
boost::python::list result;
159+
std::vector<std::string> names = vdbObject->gridNames();
160+
for( const auto &name : names )
161+
{
162+
result.append( name );
163+
}
164+
return result;
165+
}
166+
167+
} // namespace
168+
154169
BOOST_PYTHON_MODULE( _IECoreVDB )
155170
{
156171

172+
#ifdef IECOREVDB_USE_PYBIND
173+
IECorePython::PyBindConverter<openvdb::GridBase::Ptr>::registerConverters();
174+
#endif
175+
157176
IECorePython::RunTimeTypedClass<VDBObject>()
158177
.def(init<const std::string &>())
159178
.def(init<>())
160179
.def("gridNames", &::gridNames)
161180
.def("metadata", &VDBObject::metadata)
162181
.def("removeGrid", &VDBObject::removeGrid)
182+
#ifdef IECOREVDB_USE_PYBIND
183+
.def( "findGrid", (openvdb::GridBase::Ptr (VDBObject::*)( const std::string &name ))&VDBObject::findGrid )
184+
.def( "insertGrid", &VDBObject::insertGrid )
185+
#else
163186
.def("findGrid", &::findGrid)
164187
.def("insertGrid", &::insertGrid)
188+
#endif
165189
.def("unmodifiedFromFile", &VDBObject::unmodifiedFromFile)
166190
.def("fileName", &VDBObject::fileName)
167191
;

test/IECoreVDB/VDBObjectTest.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
##########################################################################
3636

3737
import os
38+
import unittest
3839
import imath
3940

4041
import IECore
@@ -240,10 +241,10 @@ def incValue( value ) :
240241

241242
d = smoke.findGrid( "density" )
242243

243-
d2Value = list( d2.citerAllValues() )[0]
244-
dValue = list( d.citerAllValues() )[0]
244+
d2Value = next( d2.citerAllValues() )
245+
dValue = next( d.citerAllValues() )
245246

246-
self.assertEqual( d2Value['value'], dValue['value'] + 1 )
247+
self.assertEqual( d2Value.value, dValue.value + 1 )
247248

248249
# we've requested mutable grids from both vdb objects so they could have been edited.
249250
self.assertFalse( smoke.unmodifiedFromFile() )

0 commit comments

Comments
 (0)