Skip to content

Commit e7d291b

Browse files
committed
Add typedesc to nanobind
Signed-off-by: Aleksandr Motsjonov <soswow@gmail.com>
1 parent 7eece77 commit e7d291b

10 files changed

Lines changed: 306 additions & 26 deletions

File tree

src/cmake/testing.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ macro (oiio_add_all_tests)
234234
IMAGEDIR oiio-images
235235
)
236236
if (OIIO_BUILD_PYTHON_NANOBIND)
237-
oiio_add_tests (python-roi-nanobind)
237+
oiio_add_tests (python-roi-nanobind python-typedesc-nanobind)
238238
endif ()
239239
endif ()
240240

src/python-nanobind/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
set (nanobind_srcs
66
py_oiio.cpp
77
py_roi.cpp
8-
py_imagespec.cpp)
8+
py_imagespec.cpp
9+
py_typedesc.cpp)
910

1011
set (nanobind_build_package_dir ${CMAKE_BINARY_DIR}/lib/python/nanobind/OpenImageIO)
1112
file (MAKE_DIRECTORY ${nanobind_build_package_dir})

src/python-nanobind/py_imagespec.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,9 @@ declare_imagespec(nb::module_& m)
4949
nb::class_<ImageSpec>(m, "ImageSpec")
5050
.def(nb::init<>())
5151
.def("__init__",
52-
[](ImageSpec* self, int xres, int yres, int nchans, int format) {
53-
new (self)
54-
ImageSpec(xres, yres, nchans,
55-
TypeDesc(static_cast<TypeDesc::BASETYPE>(
56-
format)));
52+
[](ImageSpec* self, int xres, int yres, int nchans,
53+
TypeDesc::BASETYPE format) {
54+
new (self) ImageSpec(xres, yres, nchans, TypeDesc(format));
5755
})
5856
.def_rw("x", &ImageSpec::x)
5957
.def_rw("y", &ImageSpec::y)
@@ -75,7 +73,6 @@ declare_imagespec(nb::module_& m)
7573
m.def("get_roi_full", &imagespec_get_roi_full);
7674
m.def("set_roi", &imagespec_set_roi);
7775
m.def("set_roi_full", &imagespec_set_roi_full);
78-
m.attr("UINT8") = static_cast<int>(TypeDesc::UINT8);
7976
}
8077

8178
} // namespace PyOpenImageIO

src/python-nanobind/py_oiio.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ NB_MODULE(_OpenImageIO, m)
1111

1212
PyOpenImageIO::declare_roi(m);
1313
PyOpenImageIO::declare_imagespec(m);
14+
PyOpenImageIO::declare_typedesc(m);
1415
m.attr("__version__") = OIIO_VERSION_STRING;
1516
}

src/python-nanobind/py_oiio.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
#include <OpenImageIO/imagebuf.h>
88
#include <OpenImageIO/oiioversion.h>
99
#include <OpenImageIO/strutil.h>
10+
#include <OpenImageIO/typedesc.h>
1011

1112
#include <nanobind/nanobind.h>
1213
#include <nanobind/operators.h>
1314
#include <nanobind/stl/string.h>
15+
#include <nanobind/stl/vector.h>
1416

1517
namespace nb = nanobind;
1618
using namespace nb::literals;
@@ -23,5 +25,7 @@ void
2325
declare_roi(nb::module_& m);
2426
void
2527
declare_imagespec(nb::module_& m);
28+
void
29+
declare_typedesc(nb::module_& m);
2630

2731
} // namespace PyOpenImageIO
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
// Copyright Contributors to the OpenImageIO project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
// https://github.com/AcademySoftwareFoundation/OpenImageIO
4+
5+
#include "py_oiio.h"
6+
7+
namespace {
8+
9+
OIIO_NAMESPACE_USING
10+
11+
template<class Enum>
12+
void
13+
typedesc_property(TypeDesc& t, Enum value);
14+
15+
template<>
16+
void
17+
typedesc_property<TypeDesc::BASETYPE>(TypeDesc& t, TypeDesc::BASETYPE value)
18+
{
19+
t.basetype = value;
20+
}
21+
22+
template<>
23+
void
24+
typedesc_property<TypeDesc::AGGREGATE>(TypeDesc& t, TypeDesc::AGGREGATE value)
25+
{
26+
t.aggregate = value;
27+
}
28+
29+
template<>
30+
void
31+
typedesc_property<TypeDesc::VECSEMANTICS>(TypeDesc& t,
32+
TypeDesc::VECSEMANTICS value)
33+
{
34+
t.vecsemantics = value;
35+
}
36+
37+
} // namespace
38+
39+
40+
namespace PyOpenImageIO {
41+
42+
void
43+
declare_typedesc(nb::module_& m)
44+
{
45+
using BASETYPE = TypeDesc::BASETYPE;
46+
using AGGREGATE = TypeDesc::AGGREGATE;
47+
using VECSEMANTICS = TypeDesc::VECSEMANTICS;
48+
49+
nb::enum_<BASETYPE>(m, "BASETYPE")
50+
.value("UNKNOWN", TypeDesc::UNKNOWN)
51+
.value("NONE", TypeDesc::NONE)
52+
.value("UCHAR", TypeDesc::UCHAR)
53+
.value("UINT8", TypeDesc::UINT8)
54+
.value("CHAR", TypeDesc::CHAR)
55+
.value("INT8", TypeDesc::INT8)
56+
.value("UINT16", TypeDesc::UINT16)
57+
.value("USHORT", TypeDesc::USHORT)
58+
.value("SHORT", TypeDesc::SHORT)
59+
.value("INT16", TypeDesc::INT16)
60+
.value("UINT", TypeDesc::UINT)
61+
.value("UINT32", TypeDesc::UINT32)
62+
.value("INT", TypeDesc::INT)
63+
.value("INT32", TypeDesc::INT32)
64+
.value("ULONGLONG", TypeDesc::ULONGLONG)
65+
.value("UINT64", TypeDesc::UINT64)
66+
.value("LONGLONG", TypeDesc::LONGLONG)
67+
.value("INT64", TypeDesc::INT64)
68+
.value("HALF", TypeDesc::HALF)
69+
.value("FLOAT", TypeDesc::FLOAT)
70+
.value("DOUBLE", TypeDesc::DOUBLE)
71+
.value("STRING", TypeDesc::STRING)
72+
.value("PTR", TypeDesc::PTR)
73+
.value("LASTBASE", TypeDesc::LASTBASE)
74+
.export_values();
75+
76+
nb::enum_<AGGREGATE>(m, "AGGREGATE")
77+
.value("SCALAR", TypeDesc::SCALAR)
78+
.value("VEC2", TypeDesc::VEC2)
79+
.value("VEC3", TypeDesc::VEC3)
80+
.value("VEC4", TypeDesc::VEC4)
81+
.value("MATRIX33", TypeDesc::MATRIX33)
82+
.value("MATRIX44", TypeDesc::MATRIX44)
83+
.export_values();
84+
85+
nb::enum_<VECSEMANTICS>(m, "VECSEMANTICS")
86+
.value("NOXFORM", TypeDesc::NOXFORM)
87+
.value("NOSEMANTICS", TypeDesc::NOSEMANTICS)
88+
.value("COLOR", TypeDesc::COLOR)
89+
.value("POINT", TypeDesc::POINT)
90+
.value("VECTOR", TypeDesc::VECTOR)
91+
.value("NORMAL", TypeDesc::NORMAL)
92+
.value("TIMECODE", TypeDesc::TIMECODE)
93+
.value("KEYCODE", TypeDesc::KEYCODE)
94+
.value("RATIONAL", TypeDesc::RATIONAL)
95+
.value("BOX", TypeDesc::BOX)
96+
.export_values();
97+
98+
nb::class_<TypeDesc>(m, "TypeDesc")
99+
.def_prop_rw(
100+
"basetype",
101+
[](TypeDesc t) { return BASETYPE(t.basetype); },
102+
[](TypeDesc& t, BASETYPE b) { typedesc_property(t, b); })
103+
.def_prop_rw(
104+
"aggregate",
105+
[](TypeDesc t) { return AGGREGATE(t.aggregate); },
106+
[](TypeDesc& t, AGGREGATE b) { typedesc_property(t, b); })
107+
.def_prop_rw(
108+
"vecsemantics",
109+
[](TypeDesc t) { return VECSEMANTICS(t.vecsemantics); },
110+
[](TypeDesc& t, VECSEMANTICS b) { typedesc_property(t, b); })
111+
.def_rw("arraylen", &TypeDesc::arraylen)
112+
.def(nb::init<>())
113+
.def(nb::init<const TypeDesc&>())
114+
.def(nb::init<BASETYPE>())
115+
.def(nb::init<BASETYPE, AGGREGATE>())
116+
.def(nb::init<BASETYPE, AGGREGATE, VECSEMANTICS>())
117+
.def(nb::init<BASETYPE, AGGREGATE, VECSEMANTICS, int>())
118+
.def(nb::init<const char*>())
119+
.def("c_str", [](const TypeDesc& self) { return std::string(self.c_str()); })
120+
.def("numelements", &TypeDesc::numelements)
121+
.def("basevalues", &TypeDesc::basevalues)
122+
.def("size", &TypeDesc::size)
123+
.def("elementtype", &TypeDesc::elementtype)
124+
.def("elementsize", &TypeDesc::elementsize)
125+
.def("basesize", &TypeDesc::basesize)
126+
.def("fromstring",
127+
[](TypeDesc& t, const char* typestring) { t.fromstring(typestring); })
128+
.def("equivalent", &TypeDesc::equivalent)
129+
.def("unarray", &TypeDesc::unarray)
130+
.def("is_vec2", &TypeDesc::is_vec2)
131+
.def("is_vec3", &TypeDesc::is_vec3)
132+
.def("is_vec4", &TypeDesc::is_vec4)
133+
.def("is_box2", &TypeDesc::is_box2)
134+
.def("is_box3", &TypeDesc::is_box3)
135+
.def_static("all_types_equal",
136+
[](const std::vector<TypeDesc>& types) {
137+
return TypeDesc::all_types_equal(types);
138+
})
139+
.def(nb::self == nb::self)
140+
.def(nb::self != nb::self)
141+
.def("__str__", [](TypeDesc t) { return std::string(t.c_str()); })
142+
.def("__repr__",
143+
[](TypeDesc t) {
144+
return Strutil::fmt::format("<TypeDesc '{}'>", t.c_str());
145+
});
146+
147+
m.attr("UNKNOWN") = nb::cast(TypeDesc::UNKNOWN);
148+
m.attr("NONE") = nb::cast(TypeDesc::NONE);
149+
m.attr("UCHAR") = nb::cast(TypeDesc::UCHAR);
150+
m.attr("UINT8") = nb::cast(TypeDesc::UINT8);
151+
m.attr("CHAR") = nb::cast(TypeDesc::CHAR);
152+
m.attr("INT8") = nb::cast(TypeDesc::INT8);
153+
m.attr("UINT16") = nb::cast(TypeDesc::UINT16);
154+
m.attr("USHORT") = nb::cast(TypeDesc::USHORT);
155+
m.attr("SHORT") = nb::cast(TypeDesc::SHORT);
156+
m.attr("INT16") = nb::cast(TypeDesc::INT16);
157+
m.attr("UINT") = nb::cast(TypeDesc::UINT);
158+
m.attr("UINT32") = nb::cast(TypeDesc::UINT32);
159+
m.attr("INT") = nb::cast(TypeDesc::INT);
160+
m.attr("INT32") = nb::cast(TypeDesc::INT32);
161+
m.attr("ULONGLONG") = nb::cast(TypeDesc::ULONGLONG);
162+
m.attr("UINT64") = nb::cast(TypeDesc::UINT64);
163+
m.attr("LONGLONG") = nb::cast(TypeDesc::LONGLONG);
164+
m.attr("INT64") = nb::cast(TypeDesc::INT64);
165+
m.attr("HALF") = nb::cast(TypeDesc::HALF);
166+
m.attr("FLOAT") = nb::cast(TypeDesc::FLOAT);
167+
m.attr("DOUBLE") = nb::cast(TypeDesc::DOUBLE);
168+
m.attr("STRING") = nb::cast(TypeDesc::STRING);
169+
m.attr("PTR") = nb::cast(TypeDesc::PTR);
170+
m.attr("LASTBASE") = nb::cast(TypeDesc::LASTBASE);
171+
172+
m.attr("SCALAR") = nb::cast(TypeDesc::SCALAR);
173+
m.attr("VEC2") = nb::cast(TypeDesc::VEC2);
174+
m.attr("VEC3") = nb::cast(TypeDesc::VEC3);
175+
m.attr("VEC4") = nb::cast(TypeDesc::VEC4);
176+
m.attr("MATRIX33") = nb::cast(TypeDesc::MATRIX33);
177+
m.attr("MATRIX44") = nb::cast(TypeDesc::MATRIX44);
178+
179+
m.attr("NOXFORM") = nb::cast(TypeDesc::NOXFORM);
180+
m.attr("NOSEMANTICS") = nb::cast(TypeDesc::NOSEMANTICS);
181+
m.attr("COLOR") = nb::cast(TypeDesc::COLOR);
182+
m.attr("POINT") = nb::cast(TypeDesc::POINT);
183+
m.attr("VECTOR") = nb::cast(TypeDesc::VECTOR);
184+
m.attr("NORMAL") = nb::cast(TypeDesc::NORMAL);
185+
m.attr("TIMECODE") = nb::cast(TypeDesc::TIMECODE);
186+
m.attr("KEYCODE") = nb::cast(TypeDesc::KEYCODE);
187+
m.attr("RATIONAL") = nb::cast(TypeDesc::RATIONAL);
188+
m.attr("BOX") = nb::cast(TypeDesc::BOX);
189+
190+
m.attr("TypeUnknown") = TypeUnknown;
191+
m.attr("TypeFloat") = TypeFloat;
192+
m.attr("TypeColor") = TypeColor;
193+
m.attr("TypePoint") = TypePoint;
194+
m.attr("TypeVector") = TypeVector;
195+
m.attr("TypeNormal") = TypeNormal;
196+
m.attr("TypeString") = TypeString;
197+
m.attr("TypeInt") = TypeInt;
198+
m.attr("TypeUInt") = TypeUInt;
199+
m.attr("TypeInt64") = TypeInt64;
200+
m.attr("TypeUInt64") = TypeUInt64;
201+
m.attr("TypeInt32") = TypeInt32;
202+
m.attr("TypeUInt32") = TypeUInt32;
203+
m.attr("TypeInt16") = TypeInt16;
204+
m.attr("TypeUInt16") = TypeUInt16;
205+
m.attr("TypeInt8") = TypeInt8;
206+
m.attr("TypeUInt8") = TypeUInt8;
207+
m.attr("TypeHalf") = TypeHalf;
208+
m.attr("TypeMatrix") = TypeMatrix;
209+
m.attr("TypeMatrix33") = TypeMatrix33;
210+
m.attr("TypeMatrix44") = TypeMatrix44;
211+
m.attr("TypeTimeCode") = TypeTimeCode;
212+
m.attr("TypeKeyCode") = TypeKeyCode;
213+
m.attr("TypeFloat2") = TypeFloat2;
214+
m.attr("TypeVector2") = TypeVector2;
215+
m.attr("TypeFloat4") = TypeFloat4;
216+
m.attr("TypeVector4") = TypeVector4;
217+
m.attr("TypeVector2i") = TypeVector2i;
218+
m.attr("TypeVector3i") = TypeVector3i;
219+
m.attr("TypeBox2") = TypeBox2;
220+
m.attr("TypeBox3") = TypeBox3;
221+
m.attr("TypeBox2i") = TypeBox2i;
222+
m.attr("TypeBox3i") = TypeBox3i;
223+
m.attr("TypeRational") = TypeRational;
224+
m.attr("TypeURational") = TypeURational;
225+
m.attr("TypePointer") = TypePointer;
226+
}
227+
228+
} // namespace PyOpenImageIO
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright Contributors to the OpenImageIO project.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# https://github.com/AcademySoftwareFoundation/OpenImageIO
6+
7+
refdirlist = [make_relpath(os.path.join(OIIO_TESTSUITE_ROOT, "python-typedesc", "ref"))]
8+
command += pythonbin + " src/test_typedesc_nanobind.py " + OIIO_BUILD_ROOT + " > out.txt"
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright Contributors to the OpenImageIO project.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# https://github.com/AcademySoftwareFoundation/OpenImageIO
6+
7+
from __future__ import annotations
8+
9+
import pathlib
10+
import sys
11+
12+
# runtest.py executes this file as a script, not as part of a Python package,
13+
# so relative imports are not available here. Add the TypeDesc test directory
14+
# and shared helper directory to sys.path explicitly, then import the canonical
15+
# TypeDesc test body plus the helper that loads the staged nanobind package
16+
# from build/.
17+
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[2] / "common"))
18+
sys.path.insert(
19+
0, str(pathlib.Path(__file__).resolve().parents[2] / "python-typedesc" / "src")
20+
)
21+
22+
from pythonbinding_loaders import load_nanobind_oiio_package # noqa: E402
23+
from test_typedesc import run # noqa: E402
24+
25+
26+
def main() -> int:
27+
build_root = pathlib.Path(sys.argv[1]).resolve()
28+
oiio = load_nanobind_oiio_package(build_root)
29+
30+
run(oiio)
31+
return 0
32+
33+
34+
if __name__ == "__main__":
35+
raise SystemExit(main())

testsuite/python-typedesc/run.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,3 @@
66

77

88
command += pythonbin + " src/test_typedesc.py > out.txt"
9-

0 commit comments

Comments
 (0)