Skip to content

Commit

Permalink
update to nanobind 0.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
wjakob committed Mar 8, 2023
1 parent f5020e2 commit 2ee903c
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 157 deletions.
2 changes: 1 addition & 1 deletion ext/nanobind
Submodule nanobind updated 121 files
113 changes: 59 additions & 54 deletions include/nanogui/python.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,65 +27,70 @@ extern "C" {
};

/// Provides a ``NB_OVERRIDE`` for any relevant Widget items that need to be bound.
#define NANOGUI_WIDGET_OVERLOADS(Parent) \
NB_TRAMPOLINE(Parent, 20) \
bool mouse_button_event(const ::nanogui::Vector2i &p, int button, bool down, int modifiers) override { \
NB_OVERRIDE(bool, Parent, mouse_button_event, p, button, down, modifiers); \
} \
bool mouse_motion_event(const ::nanogui::Vector2i &p, const ::nanogui::Vector2i &rel, int button, int modifiers) override { \
NB_OVERRIDE(bool, Parent, mouse_motion_event, p, rel, button, modifiers); \
} \
bool mouse_drag_event(const ::nanogui::Vector2i &p, const ::nanogui::Vector2i &rel, int button, int modifiers) override { \
NB_OVERRIDE(bool, Parent, mouse_drag_event, p, rel, button, modifiers); \
} \
bool mouse_enter_event(const ::nanogui::Vector2i &p, bool enter) override { \
NB_OVERRIDE(bool, Parent, mouse_enter_event, p, enter); \
} \
bool scroll_event(const ::nanogui::Vector2i &p, const ::nanogui::Vector2f &rel) override { \
NB_OVERRIDE(bool, Parent, scroll_event, p, rel); \
} \
bool focus_event(bool focused) override { \
NB_OVERRIDE(bool, Parent, focus_event, focused); \
} \
bool keyboard_event(int key, int scancode, int action, int modifiers) override { \
NB_OVERRIDE(bool, Parent, keyboard_event, key, scancode, action, modifiers); \
} \
bool keyboard_character_event(unsigned int codepoint) override { \
NB_OVERRIDE(bool, Parent, keyboard_character_event, codepoint); \
} \
::nanogui::Vector2i preferred_size(NVGcontext *ctx) const override { \
NB_OVERRIDE(::nanogui::Vector2i, Parent, preferred_size, ctx); \
} \
void perform_layout(NVGcontext *ctx) override { \
NB_OVERRIDE(void, Parent, perform_layout, ctx); \
} \
void draw(NVGcontext *ctx) override { \
NB_OVERRIDE(void, Parent, draw, ctx); \
}
#define NANOGUI_WIDGET_OVERLOADS(Parent) \
NB_TRAMPOLINE(Parent, 16); \
bool mouse_button_event(const ::nanogui::Vector2i &p, int button, \
bool down, int modifiers) override { \
NB_OVERRIDE(mouse_button_event, p, button, down, modifiers); \
} \
bool mouse_motion_event(const ::nanogui::Vector2i &p, \
const ::nanogui::Vector2i &rel, int button, \
int modifiers) override { \
NB_OVERRIDE(mouse_motion_event, p, rel, button, modifiers); \
} \
bool mouse_drag_event(const ::nanogui::Vector2i &p, \
const ::nanogui::Vector2i &rel, int button, \
int modifiers) override { \
NB_OVERRIDE(mouse_drag_event, p, rel, button, modifiers); \
} \
bool mouse_enter_event(const ::nanogui::Vector2i &p, bool enter) \
override { \
NB_OVERRIDE(mouse_enter_event, p, enter); \
} \
bool scroll_event(const ::nanogui::Vector2i &p, \
const ::nanogui::Vector2f &rel) override { \
NB_OVERRIDE(scroll_event, p, rel); \
} \
bool focus_event(bool focused) override { \
NB_OVERRIDE(focus_event, focused); \
} \
bool keyboard_event(int key, int scancode, int action, int modifiers) \
override { \
NB_OVERRIDE(keyboard_event, key, scancode, action, modifiers); \
} \
bool keyboard_character_event(unsigned int codepoint) override { \
NB_OVERRIDE(keyboard_character_event, codepoint); \
} \
::nanogui::Vector2i preferred_size(NVGcontext *ctx) const override { \
NB_OVERRIDE(preferred_size, ctx); \
} \
void perform_layout(NVGcontext *ctx) override { \
NB_OVERRIDE(perform_layout, ctx); \
} \
void draw(NVGcontext *ctx) override { NB_OVERRIDE(draw, ctx); }

/// Provides a ``NB_OVERRIDE`` for any relevant Layout items that need to be bound.
#define NANOGUI_LAYOUT_OVERLOADS(Parent) \
NB_TRAMPOLINE(Parent, 2) \
::nanogui::Vector2i preferred_size(NVGcontext *ctx, const ::nanogui::Widget *widget) const override { \
NB_OVERRIDE(::nanogui::Vector2i, Parent, preferred_size, ctx, widget); \
} \
void perform_layout(NVGcontext *ctx, ::nanogui::Widget *widget) const override { \
NB_OVERRIDE(void, Parent, perform_layout, ctx, widget); \
#define NANOGUI_LAYOUT_OVERLOADS(Parent) \
NB_TRAMPOLINE(Parent, 2); \
::nanogui::Vector2i preferred_size( \
NVGcontext *ctx, const ::nanogui::Widget *widget) const override { \
NB_OVERRIDE(preferred_size, ctx, widget); \
} \
void perform_layout(NVGcontext *ctx, ::nanogui::Widget *widget) \
const override { \
NB_OVERRIDE(perform_layout, ctx, widget); \
}

/// Provides a ``NB_OVERRIDE`` for any relevant Screen items that need to be bound.
#define NANOGUI_SCREEN_OVERLOADS(Parent) \
virtual void draw_all() override { \
NB_OVERRIDE(void, Parent, draw_all); \
} \
virtual void draw_contents() override { \
NB_OVERRIDE(void, Parent, draw_contents); \
} \
virtual bool drop_event(const std::vector<std::string> &filenames) override { \
NB_OVERRIDE(bool, Parent, drop_event, filenames); \
} \
virtual bool resize_event(const ::nanogui::Vector2i &size) override { \
NB_OVERRIDE(bool, Parent, resize_event, size); \
#define NANOGUI_SCREEN_OVERLOADS(Parent) \
virtual void draw_all() override { NB_OVERRIDE(draw_all); } \
virtual void draw_contents() override { NB_OVERRIDE(draw_contents); } \
virtual bool drop_event(const std::vector<std::string> &filenames) \
override { \
NB_OVERRIDE(drop_event, filenames); \
} \
virtual bool resize_event(const ::nanogui::Vector2i &size) override { \
NB_OVERRIDE(resize_event, size); \
}

NAMESPACE_BEGIN(nanobind)
Expand Down
6 changes: 2 additions & 4 deletions src/python/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,19 @@

class PyCanvas : public Canvas {
public:
using Canvas::Canvas;
NANOGUI_WIDGET_OVERLOADS(Canvas);

void draw_contents() override {
NB_OVERRIDE(void, Canvas, draw_contents);
NB_OVERRIDE(draw_contents);
}
};

class PyImageView : public ImageView {
public:
using ImageView::ImageView;
NANOGUI_WIDGET_OVERLOADS(ImageView);

void draw_contents() override {
NB_OVERRIDE(void, ImageView, draw_contents);
NB_OVERRIDE(draw_contents);
}
};

Expand Down
8 changes: 4 additions & 4 deletions src/python/color.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ void register_eigen(nb::module_ &m) {
.def(nb::init<float, float>(), D(Color, Color, 5))
.def("contrasting_color", &Color::contrasting_color,
D(Color, contrasting_color))
.def_property("r", [](const Color &c) { return c.r(); },
.def_prop_rw("r", [](const Color &c) { return c.r(); },
[](Color &c, float v) { c.r() = v; }, D(Color, r))
.def_property("g", [](const Color &c) { return c.g(); },
.def_prop_rw("g", [](const Color &c) { return c.g(); },
[](Color &c, float v) { c.g() = v; }, D(Color, g))
.def_property("b", [](const Color &c) { return c.b(); },
.def_prop_rw("b", [](const Color &c) { return c.b(); },
[](Color &c, float v) { c.b() = v; }, D(Color, b))
.def_property("w", [](const Color &c) { return c.w(); },
.def_prop_rw("w", [](const Color &c) { return c.w(); },
[](Color &c, float v) { c.w() = v; }, "Return a reference to the alpha channel.")
.def("__repr__", [](const Color &c) {
std::ostringstream oss;
Expand Down
3 changes: 0 additions & 3 deletions src/python/python.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,18 @@
#define DECLARE_LAYOUT(Name) \
class Py##Name : public Name { \
public: \
using Name::Name; \
NANOGUI_LAYOUT_OVERLOADS(Name); \
}

#define DECLARE_WIDGET(Name) \
class Py##Name : public Name { \
public: \
using Name::Name; \
NANOGUI_WIDGET_OVERLOADS(Name); \
}

#define DECLARE_SCREEN(Name) \
class Py##Name : public Name { \
public: \
using Name::Name; \
NANOGUI_WIDGET_OVERLOADS(Name); \
NANOGUI_SCREEN_OVERLOADS(Name); \
}
Expand Down
58 changes: 31 additions & 27 deletions src/python/render.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#ifdef NANOGUI_PYTHON

#include <nanobind/tensor.h>
#include <nanobind/ndarray.h>

#include "python.h"

static VariableType dtype_to_enoki(nb::dlpack::dtype dtype) {
static VariableType interpret_dlpack_dtype(nb::dlpack::dtype dtype) {
switch ((nb::dlpack::dtype_code) dtype.code) {
case nb::dlpack::dtype_code::Int:
switch (dtype.bits) {
Expand Down Expand Up @@ -44,25 +44,25 @@ static VariableType dtype_to_enoki(nb::dlpack::dtype dtype) {

static void
shader_set_buffer(Shader &shader, const std::string &name,
nb::tensor<nb::device::cpu, nb::c_contig> tensor) {
if (tensor.ndim() > 3)
throw nb::type_error("Shader::set_buffer(): tensor rank must be < 3!");
nb::ndarray<nb::device::cpu, nb::c_contig> array) {
if (array.ndim() > 3)
throw nb::type_error("Shader::set_buffer(): number of array dimensions must be < 3!");

VariableType dtype = dtype_to_enoki(tensor.dtype());
VariableType dtype = interpret_dlpack_dtype(array.dtype());

if (dtype == VariableType::Invalid)
throw nb::type_error("Shader::set_buffer(): unsupported array dtype!");

size_t dim[3] {
tensor.ndim() > 0 ? (size_t) tensor.shape(0) : 1,
tensor.ndim() > 1 ? (size_t) tensor.shape(1) : 1,
tensor.ndim() > 2 ? (size_t) tensor.shape(2) : 1
array.ndim() > 0 ? (size_t) array.shape(0) : 1,
array.ndim() > 1 ? (size_t) array.shape(1) : 1,
array.ndim() > 2 ? (size_t) array.shape(2) : 1
};

shader.set_buffer(name, dtype, tensor.ndim(), dim, tensor.data());
shader.set_buffer(name, dtype, array.ndim(), dim, array.data());
}

static nb::tensor<nb::numpy> texture_download(Texture &texture) {
static nb::ndarray<nb::numpy> texture_download(Texture &texture) {
nb::dlpack::dtype dt;

switch (texture.component_format()) {
Expand Down Expand Up @@ -90,18 +90,19 @@ static nb::tensor<nb::numpy> texture_download(Texture &texture) {

texture.download(ptr);

return nb::tensor<nb::numpy>(ptr, 3, shape, owner, nullptr, dt);
return nb::ndarray<nb::numpy>(ptr, 3, shape, owner, nullptr, dt);
}

static void texture_upload(Texture &texture, nb::tensor<nb::device::cpu, nb::c_contig> tensor) {
size_t n_channels = tensor.ndim() == 3 ? tensor.shape(2) : 1;
VariableType dtype = dtype_to_enoki(tensor.dtype()),
static void texture_upload(Texture &texture,
nb::ndarray<nb::device::cpu, nb::c_contig> array) {
size_t n_channels = array.ndim() == 3 ? array.shape(2) : 1;
VariableType dtype = interpret_dlpack_dtype(array.dtype()),
dtype_texture = (VariableType) texture.component_format();

if (tensor.ndim() != 2 && tensor.ndim() != 3)
if (array.ndim() != 2 && array.ndim() != 3)
throw std::runtime_error("Texture::upload(): expected a 2 or 3-dimensional array!");
else if (tensor.shape(0) != (size_t) texture.size().y() ||
tensor.shape(1) != (size_t) texture.size().x())
else if (array.shape(0) != (size_t) texture.size().y() ||
array.shape(1) != (size_t) texture.size().x())
throw std::runtime_error("Texture::upload(): array size does not match the texture!");
else if (n_channels != texture.channels())
throw std::runtime_error(
Expand All @@ -114,18 +115,21 @@ static void texture_upload(Texture &texture, nb::tensor<nb::device::cpu, nb::c_c
type_name(dtype) + ") does not match the texture (" +
type_name(dtype_texture) + ")!");

texture.upload((const uint8_t *) tensor.data());
texture.upload((const uint8_t *) array.data());
}

static void texture_upload_sub_region(Texture &texture, nb::tensor<nb::device::cpu, nb::c_contig> tensor, const Vector2i &origin) {
size_t n_channels = tensor.ndim() == 3 ? tensor.shape(2) : 1;
VariableType dtype = dtype_to_enoki(tensor.dtype()),
static void
texture_upload_sub_region(Texture &texture,
nb::ndarray<nb::device::cpu, nb::c_contig> array,
const Vector2i &origin) {
size_t n_channels = array.ndim() == 3 ? array.shape(2) : 1;
VariableType dtype = interpret_dlpack_dtype(array.dtype()),
dtype_texture = (VariableType) texture.component_format();

if (tensor.ndim() != 2 && tensor.ndim() != 3)
if (array.ndim() != 2 && array.ndim() != 3)
throw std::runtime_error("Texture::upload_sub_region(): expected a 2 or 3-dimensional array!");
else if (tensor.shape(0) + (size_t) origin.x() > (size_t) texture.size().y() ||
tensor.shape(1) + (size_t) origin.y() > (size_t) texture.size().x())
else if (array.shape(0) + (size_t) origin.x() > (size_t) texture.size().y() ||
array.shape(1) + (size_t) origin.y() > (size_t) texture.size().x())
throw std::runtime_error("Texture::upload_sub_region(): bounds exceed the size of the texture!");
else if (n_channels != texture.channels())
throw std::runtime_error(
Expand All @@ -139,8 +143,8 @@ static void texture_upload_sub_region(Texture &texture, nb::tensor<nb::device::c
type_name(dtype_texture) + ")!");

texture.upload_sub_region(
(const uint8_t *) tensor.data(), origin,
{ (int32_t) tensor.shape(0), (int32_t) tensor.shape(1) });
(const uint8_t *) array.data(), origin,
{ (int32_t) array.shape(0), (int32_t) array.shape(1) });
}
#endif

Expand Down
Loading

0 comments on commit 2ee903c

Please sign in to comment.