From bca4ab151d5e3a7801c6e2d6e3f0cdcffe43b605 Mon Sep 17 00:00:00 2001 From: fraguada Date: Tue, 30 Jul 2024 12:03:44 +0200 Subject: [PATCH 01/27] small update to testing.md --- docs/testing.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/testing.md b/docs/testing.md index 6eeaa0b7..48b5bc8e 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -27,6 +27,7 @@ If you want to tests agains a published version of rhino3dm.js, you would need t - `npm i rhino3dm@8.9.0-beta` for example, to install version 8.9.0-beta of rhino3dm - `npm test` to run the tests +- do not commit this change. ## python @@ -56,7 +57,7 @@ If you have built rhino3dm.net from source, you need to follow a few additional - `dotnet build` - `dotnet test` -If you want to test with a publushed version: +If you want to test with a published version: - `cd tests/dotnet/rhino3dm_test` - `dotnet add package Rhino3dm -v 8.9.0-beta` From a66ec9b53f9dec9db7624938aebe8cd7677e865f Mon Sep 17 00:00:00 2001 From: fraguada Date: Tue, 30 Jul 2024 16:02:39 +0200 Subject: [PATCH 02/27] starting to add nanobind. --- .gitmodules | 4 ++++ setup.py | 6 +++-- src/CMakeLists.txt | 33 +++++++++++++++++++++++--- src/bindings/bindings.cpp | 15 +++++++++++- src/bindings/bindings.h | 25 +++++++++++++++---- src/bindings/bnd_3dm_attributes.cpp | 7 +++++- src/bindings/bnd_3dm_attributes.h | 11 ++++++++- src/bindings/bnd_3dm_settings.cpp | 7 +++++- src/bindings/bnd_3dm_settings.h | 9 ++++++- src/bindings/bnd_annotationbase.h | 9 ++++++- src/bindings/bnd_arc.cpp | 6 ++++- src/bindings/bnd_arc.h | 9 ++++++- src/bindings/bnd_arccurve.h | 9 ++++++- src/bindings/bnd_beam.cpp | 7 +++++- src/bindings/bnd_beam.h | 9 ++++++- src/bindings/bnd_bezier.h | 9 ++++++- src/bindings/bnd_bitmap.h | 9 ++++++- src/bindings/bnd_boundingbox.h | 13 +++++++--- src/bindings/bnd_box.h | 9 ++++++- src/bindings/bnd_brep.h | 11 ++++++++- src/bindings/bnd_circle.h | 9 ++++++- src/bindings/bnd_color.cpp | 10 ++++++-- src/bindings/bnd_cone.h | 9 ++++++- src/bindings/bnd_curve.h | 9 ++++++- src/bindings/bnd_curveproxy.h | 9 ++++++- src/bindings/bnd_cylinder.h | 9 ++++++- src/bindings/bnd_decals.h | 9 ++++++- src/bindings/bnd_defines.cpp | 32 ++++++++++++++----------- src/bindings/bnd_defines.h | 25 ++++++++++++------- src/bindings/bnd_dimensionstyle.h | 9 ++++++- src/bindings/bnd_dithering.h | 9 ++++++- src/bindings/bnd_draco.h | 9 ++++++- src/bindings/bnd_ellipse.cpp | 6 ++++- src/bindings/bnd_ellipse.h | 9 ++++++- src/bindings/bnd_embedded_file.h | 9 ++++++- src/bindings/bnd_extensions.h | 9 ++++++- src/bindings/bnd_file_utilities.h | 9 ++++++- src/bindings/bnd_font.h | 9 ++++++- src/bindings/bnd_geometry.h | 9 ++++++- src/bindings/bnd_ground_plane.h | 9 ++++++- src/bindings/bnd_group.h | 9 ++++++- src/bindings/bnd_hatch.h | 9 ++++++- src/bindings/bnd_instance.h | 9 ++++++- src/bindings/bnd_intersect.h | 9 ++++++- src/bindings/bnd_layer.h | 9 ++++++- src/bindings/bnd_light.h | 9 ++++++- src/bindings/bnd_linear_workflow.h | 9 ++++++- src/bindings/bnd_linecurve.h | 9 ++++++- src/bindings/bnd_linetype.h | 27 +++++++++++++-------- src/bindings/bnd_material.h | 9 ++++++- src/bindings/bnd_mesh.h | 17 +++++++++---- src/bindings/bnd_mesh_modifiers.h | 9 ++++++- src/bindings/bnd_model_component.h | 9 ++++++- src/bindings/bnd_nurbscurve.h | 9 ++++++- src/bindings/bnd_nurbssurface.h | 9 ++++++- src/bindings/bnd_object.h | 9 ++++++- src/bindings/bnd_plane.h | 13 +++++++--- src/bindings/bnd_planesurface.h | 9 ++++++- src/bindings/bnd_point.h | 9 ++++++- src/bindings/bnd_pointcloud.h | 9 ++++++- src/bindings/bnd_pointgeometry.h | 9 ++++++- src/bindings/bnd_pointgrid.h | 9 ++++++- src/bindings/bnd_polycurve.h | 9 ++++++- src/bindings/bnd_polyline.h | 9 ++++++- src/bindings/bnd_polylinecurve.h | 9 ++++++- src/bindings/bnd_post_effects.h | 9 ++++++- src/bindings/bnd_render_channels.h | 9 ++++++- src/bindings/bnd_render_content.h | 9 ++++++- src/bindings/bnd_render_environments.h | 9 ++++++- src/bindings/bnd_revsurface.h | 9 ++++++- src/bindings/bnd_rtree.h | 9 ++++++- src/bindings/bnd_safe_frame.h | 9 ++++++- src/bindings/bnd_skylight.h | 9 ++++++- src/bindings/bnd_sphere.h | 13 +++++++--- src/bindings/bnd_subd.h | 9 ++++++- src/bindings/bnd_sun.h | 9 ++++++- src/bindings/bnd_surface.h | 9 ++++++- src/bindings/bnd_surfaceproxy.h | 9 ++++++- src/bindings/bnd_texture.h | 12 ++++++++-- src/bindings/bnd_texture_mapping.h | 9 ++++++- src/bindings/bnd_uuid.h | 7 +++++- src/bindings/bnd_viewport.h | 9 ++++++- src/bindings/bnd_xform.h | 9 ++++++- src/lib/nanobind | 1 + 84 files changed, 727 insertions(+), 130 deletions(-) create mode 160000 src/lib/nanobind diff --git a/.gitmodules b/.gitmodules index 2141d440..1c237625 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,7 @@ [submodule "src/lib/draco"] path = src/lib/draco url = https://github.com/mcneel/draco.git +[submodule "src/lib/nanobind"] + path = src/lib/nanobind + url = https://github.com/wjakob/nanobind.git + diff --git a/setup.py b/setup.py index 2ca86b12..12dc1dda 100644 --- a/setup.py +++ b/setup.py @@ -25,6 +25,8 @@ def system(cmd : List, **kwargs): try: cmd_out = sp.run(cmd, encoding='utf-8', check=True, stdout=sp.PIPE, stderr=sp.PIPE, **kwargs) except sp.CalledProcessError as e: + print(e.stderr) + print(e.output) raise RuntimeError(f"Command execution failed.\n\n{e.stderr}\n\n{e.output}") print(cmd_out.stdout) @@ -63,8 +65,8 @@ def build_extension(self, ext): print("extdir = " + extdir) print("sourcedir" + ext.sourcedir) - cmake_args = ['cmake', - f'-DPYTHON_EXECUTABLE:FILEPATH={pyexec}'] + #cmake_args = ['cmake', f'-DPYTHON_EXECUTABLE:FILEPATH={pyexec}'] + cmake_args = ['cmake', f'-DPYTHON_EXECUTABLE:FILEPATH={pyexec}', f'-DPYTHON_BINDING_LIB=NANOBIND'] cfg = 'Debug' if self.debug else 'Release' build_args = ['--config', cfg] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60db8102..05614fa0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,7 +15,20 @@ endif() if (${RHINO3DM_PY}) message("Python Compile") - add_subdirectory(lib/pybind11) + if(PYTHON_BINDING_LIB STREQUAL "NANOBIND") + message("Using nanobind") + if (CMAKE_VERSION VERSION_LESS 3.18) + set(DEV_MODULE Development) + else() + set(DEV_MODULE Development.Module) + endif() + find_package(Python COMPONENTS Interpreter ${DEV_MODULE} REQUIRED) + add_compile_definitions( NANOBIND ) + add_subdirectory(lib/nanobind) + else() + message("Using pybind11") + add_subdirectory(lib/pybind11) + endif() endif() message("NODE=${NODE}") @@ -94,12 +107,26 @@ if (${RHINO3DM_PY}) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") add_definitions(-DON_RUNTIME_LINUX) add_definitions(-DON_CLANG_CONSTRUCTOR_BUG) - pybind11_add_module(_rhino3dm ${bindings_SRC} ${opennurbs_SRC} ${zlib_SRC} ${uuid_SRC}) + if(PYTHON_BINDING_LIB STREQUAL "NANOBIND") + nanobind_add_module(_rhino3dm ${bindings_SRC} ${opennurbs_SRC} ${zlib_SRC} ${uuid_SRC}) + target_link_libraries(_rhino3dm PRIVATE nanobind) + else() + pybind11_add_module(_rhino3dm ${bindings_SRC} ${opennurbs_SRC} ${zlib_SRC} ${uuid_SRC}) + target_link_libraries(_rhino3dm PRIVATE pybind11::module) + endif() + #pybind11_add_module(_rhino3dm ${bindings_SRC} ${opennurbs_SRC} ${zlib_SRC} ${uuid_SRC}) #target_link_libraries(_rhino3dm -luuid) else() add_library(zlib_static STATIC ${zlib_SRC}) add_library(opennurbs_static STATIC ${opennurbs_SRC}) - pybind11_add_module(_rhino3dm ${bindings_SRC}) + if(PYTHON_BINDING_LIB STREQUAL "NANOBIND") + nanobind_add_module(_rhino3dm ${bindings_SRC}) + target_link_libraries(_rhino3dm PRIVATE nanobind) + else() + pybind11_add_module(_rhino3dm ${bindings_SRC}) + target_link_libraries(_rhino3dm PRIVATE pybind11::module) + endif() + target_link_libraries(_rhino3dm PRIVATE zlib_static) target_link_libraries(_rhino3dm PRIVATE opennurbs_static) endif() diff --git a/src/bindings/bindings.cpp b/src/bindings/bindings.cpp index 5deaca67..08cb1257 100644 --- a/src/bindings/bindings.cpp +++ b/src/bindings/bindings.cpp @@ -1,10 +1,16 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +NB_MODULE(_rhino3dm, m) { + m.doc() = "rhino3dm python package. OpenNURBS wrappers with a RhinoCommon style"; +#else namespace py = pybind11; PYBIND11_MODULE(_rhino3dm, m){ m.doc() = "rhino3dm python package. OpenNURBS wrappers with a RhinoCommon style"; #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; @@ -14,6 +20,7 @@ EMSCRIPTEN_BINDINGS(rhino3dm) { ON::Begin(); initFileUtilitiesBindings(m); + /* initDefines(m); initIntersectBindings(m); initPolylineBindings(m); @@ -84,13 +91,19 @@ EMSCRIPTEN_BINDINGS(rhino3dm) { initDracoBindings(m); initRTreeBindings(m); initLinetypeBindings(m); + */ + } BND_TUPLE CreateTuple(int count) { #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) + nanobind::tuple rc(count); +#else pybind11::tuple rc(count); return rc; +#endif #else emscripten::val rc(emscripten::val::array()); return rc; @@ -100,7 +113,7 @@ BND_TUPLE CreateTuple(int count) BND_TUPLE NullTuple() { #if defined(ON_PYTHON_COMPILE) - return pybind11::none(); + return py::none(); #else return emscripten::val::null(); #endif diff --git a/src/bindings/bindings.h b/src/bindings/bindings.h index 4d9315ca..5beed271 100644 --- a/src/bindings/bindings.h +++ b/src/bindings/bindings.h @@ -12,11 +12,16 @@ #include "../lib/opennurbs/opennurbs.h" #if defined(ON_PYTHON_COMPILE) -#include -#include -#include "datetime.h" -#pragma comment(lib, "rpcrt4.lib") -#pragma comment(lib, "shlwapi.lib") + #if defined(NANOBIND) + #include + #include + #else + #include + #include + #endif + #include "datetime.h" + #pragma comment(lib, "rpcrt4.lib") + #pragma comment(lib, "shlwapi.lib") #endif @@ -25,12 +30,22 @@ #endif #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) + +typedef nanobind::dict BND_DICT; +typedef nanobind::tuple BND_Color; +typedef nanobind::tuple BND_Color4f; +typedef nanobind::tuple BND_TUPLE; +typedef nanobind::handle BND_DateTime; + +#else typedef pybind11::dict BND_DICT; typedef pybind11::tuple BND_Color; typedef pybind11::tuple BND_Color4f; typedef pybind11::tuple BND_TUPLE; typedef pybind11::handle BND_DateTime; #endif +#endif #if defined(ON_WASM_COMPILE) typedef emscripten::val BND_DICT; typedef emscripten::val BND_Color; diff --git a/src/bindings/bnd_3dm_attributes.cpp b/src/bindings/bnd_3dm_attributes.cpp index 139ed02e..bf246256 100644 --- a/src/bindings/bnd_3dm_attributes.cpp +++ b/src/bindings/bnd_3dm_attributes.cpp @@ -109,8 +109,13 @@ BND_TUPLE BND_3dmObjectAttributes::GetGroupList() const ////////////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void init3dmAttributesBindings(py::module_& m) +#else namespace py = pybind11; -void init3dmAttributesBindings(pybind11::module& m) +void init3dmAttributesBindings(py::module& m) +#endif { py::class_(m, "ObjectAttributes") .def(py::init<>()) diff --git a/src/bindings/bnd_3dm_attributes.h b/src/bindings/bnd_3dm_attributes.h index 45980be8..db6c9d91 100644 --- a/src/bindings/bnd_3dm_attributes.h +++ b/src/bindings/bnd_3dm_attributes.h @@ -3,7 +3,16 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void init3dmAttributesBindings(pybind11::module& m); + +#if defined(NANOBIND) +namespace py = nanobind; +void init3dmAttributesBindings(py::module_& m); +#else +namespace py = pybind11; +void init3dmAttributesBindings(py::module& m); +#endif + + #else void init3dmAttributesBindings(void* m); #endif diff --git a/src/bindings/bnd_3dm_settings.cpp b/src/bindings/bnd_3dm_settings.cpp index b7f86b2d..78deb932 100644 --- a/src/bindings/bnd_3dm_settings.cpp +++ b/src/bindings/bnd_3dm_settings.cpp @@ -122,8 +122,13 @@ void BND_File3dmSettings::SetEarthAnchorPoint(const BND_EarthAnchorPoint& anchor } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void init3dmSettingsBindings(py::module_& m) +#else namespace py = pybind11; -void init3dmSettingsBindings(pybind11::module& m) +void init3dmSettingsBindings(py::module& m) +#endif { py::class_(m, "ConstructionPlane") .def(py::init<>()) diff --git a/src/bindings/bnd_3dm_settings.h b/src/bindings/bnd_3dm_settings.h index e0f036cd..cee6561c 100644 --- a/src/bindings/bnd_3dm_settings.h +++ b/src/bindings/bnd_3dm_settings.h @@ -4,7 +4,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void init3dmSettingsBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void init3dmSettingsBindings(py::module_& m); +#else +namespace py = pybind11; +void init3dmSettingsBindings(py::module& m); +#endif + #else void init3dmSettingsBindings(void* m); #endif diff --git a/src/bindings/bnd_annotationbase.h b/src/bindings/bnd_annotationbase.h index d44895f9..d0708b55 100644 --- a/src/bindings/bnd_annotationbase.h +++ b/src/bindings/bnd_annotationbase.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initAnnotationBaseBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initAnnotationBaseBindings(py::module_& m); +#else +namespace py = pybind11; +void initAnnotationBaseBindings(py::module& m); +#endif + #else void initAnnotationBaseBindings(void* m); #endif diff --git a/src/bindings/bnd_arc.cpp b/src/bindings/bnd_arc.cpp index 03b7bd13..5acd82cb 100644 --- a/src/bindings/bnd_arc.cpp +++ b/src/bindings/bnd_arc.cpp @@ -124,8 +124,12 @@ BND_NurbsCurve* BND_Arc::ToNurbsCurve() const } #if defined(ON_PYTHON_COMPILE) +namespace py = nanobind; +void initArcBindings(py::module_& m) +#else namespace py = pybind11; -void initArcBindings(pybind11::module& m) +void initArcBindings(py::module& m) +#endif { py::class_(m, "Arc") .def(py::init(), py::arg("circle"), py::arg("angleRadians")) diff --git a/src/bindings/bnd_arc.h b/src/bindings/bnd_arc.h index 3ebc24ac..92cde0f6 100644 --- a/src/bindings/bnd_arc.h +++ b/src/bindings/bnd_arc.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initArcBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initArcBindings(py::module_& m); +#else +namespace py = pybind11; +void initArcBindings(py::module& m); +#endif + #else void initArcBindings(void* m); #endif diff --git a/src/bindings/bnd_arccurve.h b/src/bindings/bnd_arccurve.h index 0eea89a7..8f52b29a 100644 --- a/src/bindings/bnd_arccurve.h +++ b/src/bindings/bnd_arccurve.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initArcCurveBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initArcCurveBindings(py::module_& m); +#else +namespace py = pybind11; +void initArcCurveBindings(py::module& m); +#endif + #else void initArcCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_beam.cpp b/src/bindings/bnd_beam.cpp index 86dd5ed5..35248b3e 100644 --- a/src/bindings/bnd_beam.cpp +++ b/src/bindings/bnd_beam.cpp @@ -192,8 +192,13 @@ BND_Extrusion::BND_Extrusion(ON_Extrusion* extrusion, const ON_ModelComponentRef ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initExtrusionBindings(py::module_& m) +#else namespace py = pybind11; -void initExtrusionBindings(pybind11::module& m) +void initExtrusionBindings(py::module& m) +#endif { py::class_(m, "Extrusion") .def_static("Create", &BND_Extrusion::Create, py::arg("planarCurve"), py::arg("height"), py::arg("cap")) diff --git a/src/bindings/bnd_beam.h b/src/bindings/bnd_beam.h index 65807b29..a6ff472e 100644 --- a/src/bindings/bnd_beam.h +++ b/src/bindings/bnd_beam.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initExtrusionBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initExtrusionBindings(py::module_& m); +#else +namespace py = pybind11; +void initExtrusionBindings(py::module& m); +#endif + #else void initExtrusionBindings(void* m); #endif diff --git a/src/bindings/bnd_bezier.h b/src/bindings/bnd_bezier.h index b8fd2d82..87aa8372 100644 --- a/src/bindings/bnd_bezier.h +++ b/src/bindings/bnd_bezier.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initBezierBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initBezierBindings(py::module_& m); +#else +namespace py = pybind11; +void initBezierBindings(py::module& m); +#endif + #else void initBezierBindings(void* m); #endif diff --git a/src/bindings/bnd_bitmap.h b/src/bindings/bnd_bitmap.h index 945f843d..73dcd226 100644 --- a/src/bindings/bnd_bitmap.h +++ b/src/bindings/bnd_bitmap.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initBitmapBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initBitmapBindings(py::module_& m); +#else +namespace py = pybind11; +void initBitmapBindings(py::module& m); +#endif + #else void initBitmapBindings(void* m); #endif diff --git a/src/bindings/bnd_boundingbox.h b/src/bindings/bnd_boundingbox.h index 4dba83f5..85b57da4 100644 --- a/src/bindings/bnd_boundingbox.h +++ b/src/bindings/bnd_boundingbox.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initBoundingBoxBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initBoundingBoxBindings(py::module_& m); +#else +namespace py = pybind11; +void initBoundingBoxBindings(py::module& m); +#endif + #else void initBoundingBoxBindings(void* m); #endif @@ -56,8 +63,8 @@ class BND_BoundingBox #endif #if defined(ON_PYTHON_COMPILE) - pybind11::dict Encode() const; - static BND_BoundingBox* Decode(pybind11::dict jsonObject); + py::dict Encode() const; + static BND_BoundingBox* Decode(py::dict jsonObject); #endif }; diff --git a/src/bindings/bnd_box.h b/src/bindings/bnd_box.h index a18bda8f..a0818e25 100644 --- a/src/bindings/bnd_box.h +++ b/src/bindings/bnd_box.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initBoxBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initBoxBindings(py::module_& m); +#else +namespace py = pybind11; +void initBoxBindings(py::module& m); +#endif + #else void initBoxBindings(void* m); #endif diff --git a/src/bindings/bnd_brep.h b/src/bindings/bnd_brep.h index ac1d9703..60f8a24a 100644 --- a/src/bindings/bnd_brep.h +++ b/src/bindings/bnd_brep.h @@ -2,7 +2,16 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initBrepBindings(pybind11::module& m); + +#if defined(NANOBIND) +namespace py = nanobind; +void initBrepBindings(py::module_& m); +#else +namespace py = pybind11; +void initBrepBindings(py::module& m); +#endif + + #else void initBrepBindings(void* m); #endif diff --git a/src/bindings/bnd_circle.h b/src/bindings/bnd_circle.h index 8d152a0f..ceade6e3 100644 --- a/src/bindings/bnd_circle.h +++ b/src/bindings/bnd_circle.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initCircleBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initCircleBindings(py::module_& m); +#else +namespace py = pybind11; +void initCircleBindings(py::module& m); +#endif + #else void initCircleBindings(void* m); #endif diff --git a/src/bindings/bnd_color.cpp b/src/bindings/bnd_color.cpp index 86200f94..53f89c37 100644 --- a/src/bindings/bnd_color.cpp +++ b/src/bindings/bnd_color.cpp @@ -2,9 +2,15 @@ #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +#else +namespace py = pybind11; +#endif + BND_Color ON_Color_to_Binding(const ON_Color& color) { - return pybind11::make_tuple(color.Red(), color.Green(), color.Blue(), 255 - color.Alpha()); + return py::make_tuple(color.Red(), color.Green(), color.Blue(), 255 - color.Alpha()); } ON_Color Binding_to_ON_Color(const BND_Color& color) @@ -18,7 +24,7 @@ ON_Color Binding_to_ON_Color(const BND_Color& color) BND_Color4f ON_4fColor_to_Binding(const ON_4fColor& color) { - return pybind11::make_tuple(color.Red(), color.Green(), color.Blue(), color.Alpha()); + return py::make_tuple(color.Red(), color.Green(), color.Blue(), color.Alpha()); } ON_4fColor Binding_to_ON_4fColor(const BND_Color4f& color) diff --git a/src/bindings/bnd_cone.h b/src/bindings/bnd_cone.h index f7fc972c..882688ce 100644 --- a/src/bindings/bnd_cone.h +++ b/src/bindings/bnd_cone.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initConeBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initConeBindings(py::module_& m); +#else +namespace py = pybind11; +void initConeBindings(py::module& m); +#endif + #else void initConeBindings(void* m); #endif diff --git a/src/bindings/bnd_curve.h b/src/bindings/bnd_curve.h index 37200289..31c55373 100644 --- a/src/bindings/bnd_curve.h +++ b/src/bindings/bnd_curve.h @@ -67,7 +67,14 @@ enum class CurveEvaluationSide : int #if defined(ON_PYTHON_COMPILE) -void initCurveBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initCurveBindings(py::module_& m); +#else +namespace py = pybind11; +void initCurveBindings(py::module& m); +#endif + #else void initCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_curveproxy.h b/src/bindings/bnd_curveproxy.h index ce2bf8e0..fadbe8fb 100644 --- a/src/bindings/bnd_curveproxy.h +++ b/src/bindings/bnd_curveproxy.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initCurveProxyBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initCurveProxyBindings(py::module_& m); +#else +namespace py = pybind11; +void initCurveProxyBindings(py::module& m); +#endif + #else void initCurveProxyBindings(void* m); #endif diff --git a/src/bindings/bnd_cylinder.h b/src/bindings/bnd_cylinder.h index 105a848e..9a64e00f 100644 --- a/src/bindings/bnd_cylinder.h +++ b/src/bindings/bnd_cylinder.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initCylinderBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initCylinderBindings(py::module_& m); +#else +namespace py = pybind11; +void initCylinderBindings(py::module& m); +#endif + #else void initCylinderBindings(void* m); #endif diff --git a/src/bindings/bnd_decals.h b/src/bindings/bnd_decals.h index 9e795bdd..a2f05779 100644 --- a/src/bindings/bnd_decals.h +++ b/src/bindings/bnd_decals.h @@ -20,7 +20,14 @@ enum class Projections : int }; #if defined(ON_PYTHON_COMPILE) -void initDecalBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initDecalBindings(py::module_& m); +#else +namespace py = pybind11; +void initDecalBindings(py::module& m); +#endif + #else void initDecalBindings(void* m); #endif diff --git a/src/bindings/bnd_defines.cpp b/src/bindings/bnd_defines.cpp index c0e7736f..fb14a52b 100644 --- a/src/bindings/bnd_defines.cpp +++ b/src/bindings/bnd_defines.cpp @@ -29,8 +29,12 @@ static std::vector ArrowPoints(ON_Arrowhead::arrow_type arrowType, d } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +#else namespace py = pybind11; -void initDefines(pybind11::module& m) +#endif +void initDefines(py::module& m) { py::enum_(m, "ComponentIndexType") .value("InvalidType", ON_COMPONENT_INDEX::TYPE::invalid_type) @@ -316,25 +320,25 @@ void initDefines(pybind11::module& m) ; } -pybind11::dict PointToDict(const ON_3dPoint& point) +py::dict PointToDict(const ON_3dPoint& point) { - pybind11::dict rc; + py::dict rc; rc["X"] = point.x; rc["Y"] = point.y; rc["Z"] = point.z; return rc; } -pybind11::dict VectorToDict(const ON_3dVector& vector) +py::dict VectorToDict(const ON_3dVector& vector) { - pybind11::dict rc; + py::dict rc; rc["X"] = vector.x; rc["Y"] = vector.y; rc["Z"] = vector.z; return rc; } -pybind11::dict PlaneToDict(const ON_Plane& plane) +py::dict PlaneToDict(const ON_Plane& plane) { - pybind11::dict rc; + py::dict rc; rc["Origin"] = PointToDict(plane.origin); rc["XAxis"] = VectorToDict(plane.xaxis); rc["YAxis"] = VectorToDict(plane.yaxis); @@ -342,7 +346,7 @@ pybind11::dict PlaneToDict(const ON_Plane& plane) return rc; } -ON_3dPoint PointFromDict(pybind11::dict& dict) +ON_3dPoint PointFromDict(py::dict& dict) { ON_3dVector rc; rc.x = dict["X"].cast(); @@ -350,21 +354,21 @@ ON_3dPoint PointFromDict(pybind11::dict& dict) rc.z = dict["Z"].cast(); return rc; } -ON_3dVector VectorFromDict(pybind11::dict& dict) +ON_3dVector VectorFromDict(py::dict& dict) { ON_3dPoint pt = PointFromDict(dict); return ON_3dVector(pt.x, pt.y, pt.z); } -ON_Plane PlaneFromDict(pybind11::dict& dict) +ON_Plane PlaneFromDict(py::dict& dict) { ON_Plane plane; - pybind11::dict d = dict["Origin"].cast(); + py::dict d = dict["Origin"].cast(); plane.origin = PointFromDict(d); - d = dict["XAxis"].cast(); + d = dict["XAxis"].cast(); plane.xaxis = VectorFromDict(d); - d = dict["YAxis"].cast(); + d = dict["YAxis"].cast(); plane.yaxis = VectorFromDict(d); - d = dict["ZAxis"].cast(); + d = dict["ZAxis"].cast(); plane.zaxis = VectorFromDict(d); plane.UpdateEquation(); return plane; diff --git a/src/bindings/bnd_defines.h b/src/bindings/bnd_defines.h index b380012d..cd07cb1b 100644 --- a/src/bindings/bnd_defines.h +++ b/src/bindings/bnd_defines.h @@ -4,14 +4,23 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initDefines(pybind11::module& m); - -pybind11::dict PointToDict(const ON_3dPoint& point); -pybind11::dict VectorToDict(const ON_3dVector& vector); -pybind11::dict PlaneToDict(const ON_Plane& plane); -ON_3dPoint PointFromDict(pybind11::dict& dict); -ON_3dVector VectorFromDict(pybind11::dict& dict); -ON_Plane PlaneFromDict(pybind11::dict& dict); + +#if defined(NANOBIND) +namespace py = nanobind; +void initDefines(py::module_& m); +#else +namespace py = pybind11; +void initDefines(py::module& m); +#endif + + + +py::dict PointToDict(const ON_3dPoint& point); +py::dict VectorToDict(const ON_3dVector& vector); +py::dict PlaneToDict(const ON_Plane& plane); +ON_3dPoint PointFromDict(py::dict& dict); +ON_3dVector VectorFromDict(py::dict& dict); +ON_Plane PlaneFromDict(py::dict& dict); #else void initDefines(void* m); diff --git a/src/bindings/bnd_dimensionstyle.h b/src/bindings/bnd_dimensionstyle.h index db53c760..dbfc7382 100644 --- a/src/bindings/bnd_dimensionstyle.h +++ b/src/bindings/bnd_dimensionstyle.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initDimensionStyleBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initDimensionStyleBindings(py::module_& m); +#else +namespace py = pybind11; +void initDimensionStyleBindings(py::module& m); +#endif + #else void initDimensionStyleBindings(void* m); #endif diff --git a/src/bindings/bnd_dithering.h b/src/bindings/bnd_dithering.h index 8b2e97d1..bfda2836 100644 --- a/src/bindings/bnd_dithering.h +++ b/src/bindings/bnd_dithering.h @@ -4,7 +4,14 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initDitheringBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initDitheringBindings(py::module_& m); +#else +namespace py = pybind11; +void initDitheringBindings(py::module& m); +#endif + #else void initDitheringBindings(void* m); #endif diff --git a/src/bindings/bnd_draco.h b/src/bindings/bnd_draco.h index b6fd5d2b..6acc5e0e 100644 --- a/src/bindings/bnd_draco.h +++ b/src/bindings/bnd_draco.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initDracoBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initDracoBindings(py::module_& m); +#else +namespace py = pybind11; +void initDracoBindings(py::module& m); +#endif + #else void initDracoBindings(void* m); #endif diff --git a/src/bindings/bnd_ellipse.cpp b/src/bindings/bnd_ellipse.cpp index ed749cc6..eb3d369c 100644 --- a/src/bindings/bnd_ellipse.cpp +++ b/src/bindings/bnd_ellipse.cpp @@ -2,8 +2,12 @@ #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +#else namespace py = pybind11; -void initEllipseBindings(pybind11::module& m) +#endif +void initEllipseBindings(py::module& m) { py::class_(m, "Ellipse") ; diff --git a/src/bindings/bnd_ellipse.h b/src/bindings/bnd_ellipse.h index 484fd08d..d605806e 100644 --- a/src/bindings/bnd_ellipse.h +++ b/src/bindings/bnd_ellipse.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initEllipseBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initEllipseBindings(py::module_& m); +#else +namespace py = pybind11; +void initEllipseBindings(py::module& m); +#endif + #else void initEllipseBindings(void* m); #endif diff --git a/src/bindings/bnd_embedded_file.h b/src/bindings/bnd_embedded_file.h index 06e17104..7c50b603 100644 --- a/src/bindings/bnd_embedded_file.h +++ b/src/bindings/bnd_embedded_file.h @@ -4,7 +4,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initEmbeddedFileBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initEmbeddedFileBindings(py::module_& m); +#else +namespace py = pybind11; +void initEmbeddedFileBindings(py::module& m); +#endif + #else void initEmbeddedFileBindings(void* m); #endif diff --git a/src/bindings/bnd_extensions.h b/src/bindings/bnd_extensions.h index 64c5afa8..0ea7ae22 100644 --- a/src/bindings/bnd_extensions.h +++ b/src/bindings/bnd_extensions.h @@ -4,7 +4,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initExtensionsBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initExtensionsBindings(py::module_& m); +#else +namespace py = pybind11; +void initExtensionsBindings(py::module& m); +#endif + #else void initExtensionsBindings(void* m); #endif diff --git a/src/bindings/bnd_file_utilities.h b/src/bindings/bnd_file_utilities.h index b8abf3f7..4aed0879 100644 --- a/src/bindings/bnd_file_utilities.h +++ b/src/bindings/bnd_file_utilities.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initFileUtilitiesBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initFileUtilitiesBindings(py::module_& m); +#else +namespace py = pybind11; +void initFileUtilitiesBindings(py::module& m); +#endif + #else void initFileUtilitiesBindings(void* m); #endif diff --git a/src/bindings/bnd_font.h b/src/bindings/bnd_font.h index aaa60ded..527c21e1 100644 --- a/src/bindings/bnd_font.h +++ b/src/bindings/bnd_font.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initFontBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initFontBindings(py::module_& m); +#else +namespace py = pybind11; +void initFontBindings(py::module& m); +#endif + #else void initFontBindings(void* m); #endif diff --git a/src/bindings/bnd_geometry.h b/src/bindings/bnd_geometry.h index 290f6dad..74da2888 100644 --- a/src/bindings/bnd_geometry.h +++ b/src/bindings/bnd_geometry.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initGeometryBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initGeometryBindings(py::module_& m); +#else +namespace py = pybind11; +void initGeometryBindings(py::module& m); +#endif + #else void initGeometryBindings(void* m); #endif diff --git a/src/bindings/bnd_ground_plane.h b/src/bindings/bnd_ground_plane.h index e6db9ea4..d603cadc 100644 --- a/src/bindings/bnd_ground_plane.h +++ b/src/bindings/bnd_ground_plane.h @@ -4,7 +4,14 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initGroundPlaneBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initGroundPlaneBindings(py::module_& m); +#else +namespace py = pybind11; +void initGroundPlaneBindings(py::module& m); +#endif + #else void initGroundPlaneBindings(void* m); #endif diff --git a/src/bindings/bnd_group.h b/src/bindings/bnd_group.h index 37273ed3..2edae193 100644 --- a/src/bindings/bnd_group.h +++ b/src/bindings/bnd_group.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initGroupBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initGroupBindings(py::module_& m); +#else +namespace py = pybind11; +void initGroupBindings(py::module& m); +#endif + #else void initGroupBindings(void* m); #endif diff --git a/src/bindings/bnd_hatch.h b/src/bindings/bnd_hatch.h index 83f1a756..934588c1 100644 --- a/src/bindings/bnd_hatch.h +++ b/src/bindings/bnd_hatch.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initHatchBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initHatchBindings(py::module_& m); +#else +namespace py = pybind11; +void initHatchBindings(py::module& m); +#endif + #else void initHatchBindings(void* m); #endif diff --git a/src/bindings/bnd_instance.h b/src/bindings/bnd_instance.h index 6f15258c..95330290 100644 --- a/src/bindings/bnd_instance.h +++ b/src/bindings/bnd_instance.h @@ -11,7 +11,14 @@ enum class InstanceDefinitionUpdateType : int }; #if defined(ON_PYTHON_COMPILE) -void initInstanceBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initInstanceBindings(py::module_& m); +#else +namespace py = pybind11; +void initInstanceBindings(py::module& m); +#endif + #else void initInstanceBindings(void* m); #endif diff --git a/src/bindings/bnd_intersect.h b/src/bindings/bnd_intersect.h index 626aedc5..2473ed1a 100644 --- a/src/bindings/bnd_intersect.h +++ b/src/bindings/bnd_intersect.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initIntersectBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initIntersectBindings(py::module_& m); +#else +namespace py = pybind11; +void initIntersectBindings(py::module& m); +#endif + #else void initIntersectBindings(void* m); #endif diff --git a/src/bindings/bnd_layer.h b/src/bindings/bnd_layer.h index 7d8ac111..df363084 100644 --- a/src/bindings/bnd_layer.h +++ b/src/bindings/bnd_layer.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initLayerBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initLayerBindings(py::module_& m); +#else +namespace py = pybind11; +void initLayerBindings(py::module& m); +#endif + #else void initLayerBindings(void* m); #endif diff --git a/src/bindings/bnd_light.h b/src/bindings/bnd_light.h index b2a37b05..3e01f683 100644 --- a/src/bindings/bnd_light.h +++ b/src/bindings/bnd_light.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initLightBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initLightBindings(py::module_& m); +#else +namespace py = pybind11; +void initLightBindings(py::module& m); +#endif + #else void initLightBindings(void* m); #endif diff --git a/src/bindings/bnd_linear_workflow.h b/src/bindings/bnd_linear_workflow.h index 37a21290..8a021fcd 100644 --- a/src/bindings/bnd_linear_workflow.h +++ b/src/bindings/bnd_linear_workflow.h @@ -4,7 +4,14 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initLinearWorkflowBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initLinearWorkflowBindings(py::module_& m); +#else +namespace py = pybind11; +void initLinearWorkflowBindings(py::module& m); +#endif + #else void initLinearWorkflowBindings(void* m); #endif diff --git a/src/bindings/bnd_linecurve.h b/src/bindings/bnd_linecurve.h index a1c189d2..d1d93ac0 100644 --- a/src/bindings/bnd_linecurve.h +++ b/src/bindings/bnd_linecurve.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initLineCurveBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initLineCurveBindings(py::module_& m); +#else +namespace py = pybind11; +void initLineCurveBindings(py::module& m); +#endif + #else void initLineCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_linetype.h b/src/bindings/bnd_linetype.h index 32314741..20710ac3 100644 --- a/src/bindings/bnd_linetype.h +++ b/src/bindings/bnd_linetype.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initLinetypeBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initLinetypeBindings(py::module_& m); +#else +namespace py = pybind11; +void initLinetypeBindings(py::module& m); +#endif + #else void initLinetypeBindings(void* m); #endif @@ -46,15 +53,15 @@ class BND_Linetype : public BND_ModelComponent #if defined(ON_PYTHON_COMPILE) - static BND_Linetype* Border(pybind11::object /*self*/) { return new BND_Linetype(ON_Linetype::Border); } - static BND_Linetype* ByLayer(pybind11::object /*self*/) { return new BND_Linetype(ON_Linetype::ByLayer); } - static BND_Linetype* ByParent(pybind11::object /*self*/) { return new BND_Linetype(ON_Linetype::ByParent); } - static BND_Linetype* Center(pybind11::object /*self*/) { return new BND_Linetype(ON_Linetype::Center); } - static BND_Linetype* Continuous(pybind11::object /*self*/) { return new BND_Linetype(ON_Linetype::Continuous); } - static BND_Linetype* DashDot(pybind11::object /*self*/) { return new BND_Linetype(ON_Linetype::DashDot); } - static BND_Linetype* Dashed(pybind11::object /*self*/) { return new BND_Linetype(ON_Linetype::Dashed); } - static BND_Linetype* Dots(pybind11::object /*self*/) { return new BND_Linetype(ON_Linetype::Dots); } - static BND_Linetype* Hidden(pybind11::object /*self*/) { return new BND_Linetype(ON_Linetype::Hidden); } + static BND_Linetype* Border(py::object /*self*/) { return new BND_Linetype(ON_Linetype::Border); } + static BND_Linetype* ByLayer(py::object /*self*/) { return new BND_Linetype(ON_Linetype::ByLayer); } + static BND_Linetype* ByParent(py::object /*self*/) { return new BND_Linetype(ON_Linetype::ByParent); } + static BND_Linetype* Center(py::object /*self*/) { return new BND_Linetype(ON_Linetype::Center); } + static BND_Linetype* Continuous(py::object /*self*/) { return new BND_Linetype(ON_Linetype::Continuous); } + static BND_Linetype* DashDot(py::object /*self*/) { return new BND_Linetype(ON_Linetype::DashDot); } + static BND_Linetype* Dashed(py::object /*self*/) { return new BND_Linetype(ON_Linetype::Dashed); } + static BND_Linetype* Dots(py::object /*self*/) { return new BND_Linetype(ON_Linetype::Dots); } + static BND_Linetype* Hidden(py::object /*self*/) { return new BND_Linetype(ON_Linetype::Hidden); } #else static BND_Linetype* Border() { return new BND_Linetype(ON_Linetype::Border); } static BND_Linetype* ByLayer() { return new BND_Linetype(ON_Linetype::ByLayer); } diff --git a/src/bindings/bnd_material.h b/src/bindings/bnd_material.h index 4e7b1029..fb75d771 100644 --- a/src/bindings/bnd_material.h +++ b/src/bindings/bnd_material.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initMaterialBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initMaterialBindings(py::module_& m); +#else +namespace py = pybind11; +void initMaterialBindings(py::module& m); +#endif + #else void initMaterialBindings(void* m); #endif diff --git a/src/bindings/bnd_mesh.h b/src/bindings/bnd_mesh.h index 6fab24c3..ad392182 100644 --- a/src/bindings/bnd_mesh.h +++ b/src/bindings/bnd_mesh.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initMeshBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initMeshBindings(py::module_& m); +#else +namespace py = pybind11; +void initMeshBindings(py::module& m); +#endif + #else void initMeshBindings(void* m); #endif @@ -18,10 +25,10 @@ class BND_MeshingParameters BND_MeshingParameters(const ON_MeshParameters& mp) : m_mesh_parameters(mp) {} #if defined(ON_PYTHON_COMPILE) - static BND_MeshingParameters Default(pybind11::object /*self*/) { return BND_MeshingParameters(ON_MeshParameters::DefaultMesh); } - static BND_MeshingParameters FastRenderMesh(pybind11::object /*self*/) { return BND_MeshingParameters(ON_MeshParameters::FastRenderMesh); } - static BND_MeshingParameters QualityRenderMesh(pybind11::object /*self*/) { return BND_MeshingParameters(ON_MeshParameters::QualityRenderMesh); } - static BND_MeshingParameters DefaultAnalysisMesh(pybind11::object /*self*/) { return BND_MeshingParameters(ON_MeshParameters::DefaultAnalysisMesh); } + static BND_MeshingParameters Default(py::object /*self*/) { return BND_MeshingParameters(ON_MeshParameters::DefaultMesh); } + static BND_MeshingParameters FastRenderMesh(py::object /*self*/) { return BND_MeshingParameters(ON_MeshParameters::FastRenderMesh); } + static BND_MeshingParameters QualityRenderMesh(py::object /*self*/) { return BND_MeshingParameters(ON_MeshParameters::QualityRenderMesh); } + static BND_MeshingParameters DefaultAnalysisMesh(py::object /*self*/) { return BND_MeshingParameters(ON_MeshParameters::DefaultAnalysisMesh); } #else static BND_MeshingParameters Default() { return BND_MeshingParameters(ON_MeshParameters::DefaultMesh); } static BND_MeshingParameters FastRenderMesh() { return BND_MeshingParameters(ON_MeshParameters::FastRenderMesh); } diff --git a/src/bindings/bnd_mesh_modifiers.h b/src/bindings/bnd_mesh_modifiers.h index 87e2e752..a9ebaa6d 100644 --- a/src/bindings/bnd_mesh_modifiers.h +++ b/src/bindings/bnd_mesh_modifiers.h @@ -4,7 +4,14 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initMeshModifierBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initMeshModifierBindings(py::module_& m); +#else +namespace py = pybind11; +void initMeshModifierBindings(py::module& m); +#endif + #else void initMeshModifierBindings(void* m); #endif diff --git a/src/bindings/bnd_model_component.h b/src/bindings/bnd_model_component.h index d29bffab..e5f36dfd 100644 --- a/src/bindings/bnd_model_component.h +++ b/src/bindings/bnd_model_component.h @@ -43,7 +43,14 @@ class BND_ModelComponent : public BND_CommonObject #if defined(ON_PYTHON_COMPILE) -void initModelComponentBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initModelComponentBindings(py::module_& m); +#else +namespace py = pybind11; +void initModelComponentBindings(py::module& m); +#endif + #else void initModelComponentBindings(void* m); #endif diff --git a/src/bindings/bnd_nurbscurve.h b/src/bindings/bnd_nurbscurve.h index a473f8c4..6abb4d58 100644 --- a/src/bindings/bnd_nurbscurve.h +++ b/src/bindings/bnd_nurbscurve.h @@ -4,7 +4,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initNurbsCurveBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initNurbsCurveBindings(py::module_& m); +#else +namespace py = pybind11; +void initNurbsCurveBindings(py::module& m); +#endif + #else void initNurbsCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_nurbssurface.h b/src/bindings/bnd_nurbssurface.h index c82d0c70..da66d3e0 100644 --- a/src/bindings/bnd_nurbssurface.h +++ b/src/bindings/bnd_nurbssurface.h @@ -4,7 +4,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initNurbsSurfaceBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initNurbsSurfaceBindings(py::module_& m); +#else +namespace py = pybind11; +void initNurbsSurfaceBindings(py::module& m); +#endif + #else void initNurbsSurfaceBindings(void* m); #endif diff --git a/src/bindings/bnd_object.h b/src/bindings/bnd_object.h index 58c1b8d0..a5b2df27 100644 --- a/src/bindings/bnd_object.h +++ b/src/bindings/bnd_object.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initObjectBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initObjectBindings(py::module_& m); +#else +namespace py = pybind11; +void initObjectBindings(py::module& m); +#endif + #else void initObjectBindings(void* m); #endif diff --git a/src/bindings/bnd_plane.h b/src/bindings/bnd_plane.h index b7fe5180..9a2eb35c 100644 --- a/src/bindings/bnd_plane.h +++ b/src/bindings/bnd_plane.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initPlaneBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initPlaneBindings(py::module_& m); +#else +namespace py = pybind11; +void initPlaneBindings(py::module& m); +#endif + #else void initPlaneBindings(void* m); #endif @@ -36,8 +43,8 @@ class BND_Plane #endif #if defined(ON_PYTHON_COMPILE) - pybind11::dict Encode() const; - static BND_Plane* Decode(pybind11::dict jsonObject); + py::dict Encode() const; + static BND_Plane* Decode(py::dict jsonObject); #endif ON_3dPoint m_origin; diff --git a/src/bindings/bnd_planesurface.h b/src/bindings/bnd_planesurface.h index 7e03c1fd..6aa96d0d 100644 --- a/src/bindings/bnd_planesurface.h +++ b/src/bindings/bnd_planesurface.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initPlaneSurfaceBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initPlaneSurfaceBindings(py::module_& m); +#else +namespace py = pybind11; +void initPlaneSurfaceBindings(py::module& m); +#endif + #else void initPlaneSurfaceBindings(void* m); #endif diff --git a/src/bindings/bnd_point.h b/src/bindings/bnd_point.h index 86a78018..342a62e3 100644 --- a/src/bindings/bnd_point.h +++ b/src/bindings/bnd_point.h @@ -6,7 +6,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initPointBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initPointBindings(py::module_& m); +#else +namespace py = pybind11; +void initPointBindings(py::module& m); +#endif + #else void initPointBindings(void* m); #endif diff --git a/src/bindings/bnd_pointcloud.h b/src/bindings/bnd_pointcloud.h index ecedc2c0..803648e7 100644 --- a/src/bindings/bnd_pointcloud.h +++ b/src/bindings/bnd_pointcloud.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initPointCloudBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initPointCloudBindings(py::module_& m); +#else +namespace py = pybind11; +void initPointCloudBindings(py::module& m); +#endif + #else void initPointCloudBindings(void* m); #endif diff --git a/src/bindings/bnd_pointgeometry.h b/src/bindings/bnd_pointgeometry.h index 8df5697b..0bcc235c 100644 --- a/src/bindings/bnd_pointgeometry.h +++ b/src/bindings/bnd_pointgeometry.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initPointGeometryBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initPointGeometryBindings(py::module_& m); +#else +namespace py = pybind11; +void initPointGeometryBindings(py::module& m); +#endif + #else void initPointGeometryBindings(void* m); #endif diff --git a/src/bindings/bnd_pointgrid.h b/src/bindings/bnd_pointgrid.h index c0017685..c568830a 100644 --- a/src/bindings/bnd_pointgrid.h +++ b/src/bindings/bnd_pointgrid.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initPointGridBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initPointGridBindings(py::module_& m); +#else +namespace py = pybind11; +void initPointGridBindings(py::module& m); +#endif + #else void initPointGridBindings(void* m); #endif diff --git a/src/bindings/bnd_polycurve.h b/src/bindings/bnd_polycurve.h index 169ad25d..0cee8286 100644 --- a/src/bindings/bnd_polycurve.h +++ b/src/bindings/bnd_polycurve.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initPolyCurveBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initPolyCurveBindings(py::module_& m); +#else +namespace py = pybind11; +void initPolyCurveBindings(py::module& m); +#endif + #else void initPolyCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_polyline.h b/src/bindings/bnd_polyline.h index a7c0d2bd..c8de3a4f 100644 --- a/src/bindings/bnd_polyline.h +++ b/src/bindings/bnd_polyline.h @@ -2,7 +2,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initPolylineBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initPolylineBindings(py::module_& m); +#else +namespace py = pybind11; +void initPolylineBindings(py::module& m); +#endif + #else void initPolylineBindings(void* m); #endif diff --git a/src/bindings/bnd_polylinecurve.h b/src/bindings/bnd_polylinecurve.h index 0801a8f9..ebd21ad0 100644 --- a/src/bindings/bnd_polylinecurve.h +++ b/src/bindings/bnd_polylinecurve.h @@ -2,7 +2,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initPolylineCurveBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initPolylineCurveBindings(py::module_& m); +#else +namespace py = pybind11; +void initPolylineCurveBindings(py::module& m); +#endif + #else void initPolylineCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_post_effects.h b/src/bindings/bnd_post_effects.h index d2df3451..538dda25 100644 --- a/src/bindings/bnd_post_effects.h +++ b/src/bindings/bnd_post_effects.h @@ -4,7 +4,14 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initPostEffectBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initPostEffectBindings(py::module_& m); +#else +namespace py = pybind11; +void initPostEffectBindings(py::module& m); +#endif + #else void initPostEffectBindings(void* m); #endif diff --git a/src/bindings/bnd_render_channels.h b/src/bindings/bnd_render_channels.h index 5ff7cd0f..c2dd6539 100644 --- a/src/bindings/bnd_render_channels.h +++ b/src/bindings/bnd_render_channels.h @@ -4,7 +4,14 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initRenderChannelsBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initRenderChannelsBindings(py::module_& m); +#else +namespace py = pybind11; +void initRenderChannelsBindings(py::module& m); +#endif + #else void initRenderChannelsBindings(void* m); #endif diff --git a/src/bindings/bnd_render_content.h b/src/bindings/bnd_render_content.h index b997fdfa..bde9a9da 100644 --- a/src/bindings/bnd_render_content.h +++ b/src/bindings/bnd_render_content.h @@ -4,7 +4,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initRenderContentBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initRenderContentBindings(py::module_& m); +#else +namespace py = pybind11; +void initRenderContentBindings(py::module& m); +#endif + #else void initRenderContentBindings(void* m); #endif diff --git a/src/bindings/bnd_render_environments.h b/src/bindings/bnd_render_environments.h index db57e49d..7d1dc377 100644 --- a/src/bindings/bnd_render_environments.h +++ b/src/bindings/bnd_render_environments.h @@ -4,7 +4,14 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initRenderEnvironmentsBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initRenderEnvironmentsBindings(py::module_& m); +#else +namespace py = pybind11; +void initRenderEnvironmentsBindings(py::module& m); +#endif + #else void initRenderEnvironmentsBindings(void* m); #endif diff --git a/src/bindings/bnd_revsurface.h b/src/bindings/bnd_revsurface.h index f5e7fe7b..eae712eb 100644 --- a/src/bindings/bnd_revsurface.h +++ b/src/bindings/bnd_revsurface.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initRevSurfaceBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initRevSurfaceBindings(py::module_& m); +#else +namespace py = pybind11; +void initRevSurfaceBindings(py::module& m); +#endif + #else void initRevSurfaceBindings(void* m); #endif diff --git a/src/bindings/bnd_rtree.h b/src/bindings/bnd_rtree.h index 0b35eb0b..5428860e 100644 --- a/src/bindings/bnd_rtree.h +++ b/src/bindings/bnd_rtree.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initRTreeBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initRTreeBindings(py::module_& m); +#else +namespace py = pybind11; +void initRTreeBindings(py::module& m); +#endif + #else void initRTreeBindings(void* m); #endif diff --git a/src/bindings/bnd_safe_frame.h b/src/bindings/bnd_safe_frame.h index f8842495..235798fc 100644 --- a/src/bindings/bnd_safe_frame.h +++ b/src/bindings/bnd_safe_frame.h @@ -4,7 +4,14 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initSafeFrameBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initSafeFrameBindings(py::module_& m); +#else +namespace py = pybind11; +void initSafeFrameBindings(py::module& m); +#endif + #else void initSafeFrameBindings(void* m); #endif diff --git a/src/bindings/bnd_skylight.h b/src/bindings/bnd_skylight.h index a361e65e..8db42fb5 100644 --- a/src/bindings/bnd_skylight.h +++ b/src/bindings/bnd_skylight.h @@ -4,7 +4,14 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initSkylightBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initSkylightBindings(py::module_& m); +#else +namespace py = pybind11; +void initSkylightBindings(py::module& m); +#endif + #else void initSkylightBindings(void* m); #endif diff --git a/src/bindings/bnd_sphere.h b/src/bindings/bnd_sphere.h index f9f870d3..02b37d5b 100644 --- a/src/bindings/bnd_sphere.h +++ b/src/bindings/bnd_sphere.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initSphereBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initSphereBindings(py::module_& m); +#else +namespace py = pybind11; +void initSphereBindings(py::module& m); +#endif + #else void initSphereBindings(void* m); #endif @@ -54,8 +61,8 @@ class BND_Sphere #endif #if defined(ON_PYTHON_COMPILE) - pybind11::dict Encode() const; - static BND_Sphere* Decode(pybind11::dict jsonObject); + py::dict Encode() const; + static BND_Sphere* Decode(py::dict jsonObject); #endif }; diff --git a/src/bindings/bnd_subd.h b/src/bindings/bnd_subd.h index 7d089c54..f84f5afd 100644 --- a/src/bindings/bnd_subd.h +++ b/src/bindings/bnd_subd.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initSubDBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initSubDBindings(py::module_& m); +#else +namespace py = pybind11; +void initSubDBindings(py::module& m); +#endif + #else void initSubDBindings(void* m); #endif diff --git a/src/bindings/bnd_sun.h b/src/bindings/bnd_sun.h index f806d6ca..26e79047 100644 --- a/src/bindings/bnd_sun.h +++ b/src/bindings/bnd_sun.h @@ -4,7 +4,14 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initSunBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initSunBindings(py::module_& m); +#else +namespace py = pybind11; +void initSunBindings(py::module& m); +#endif + #else void initSunBindings(void* m); #endif diff --git a/src/bindings/bnd_surface.h b/src/bindings/bnd_surface.h index e307d2d5..b76ad04a 100644 --- a/src/bindings/bnd_surface.h +++ b/src/bindings/bnd_surface.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initSurfaceBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initSurfaceBindings(py::module_& m); +#else +namespace py = pybind11; +void initSurfaceBindings(py::module& m); +#endif + #else void initSurfaceBindings(void* m); #endif diff --git a/src/bindings/bnd_surfaceproxy.h b/src/bindings/bnd_surfaceproxy.h index 1a1b5ff9..10795c3f 100644 --- a/src/bindings/bnd_surfaceproxy.h +++ b/src/bindings/bnd_surfaceproxy.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initSurfaceProxyBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initSurfaceProxyBindings(py::module_& m); +#else +namespace py = pybind11; +void initSurfaceProxyBindings(py::module& m); +#endif + #else void initSurfaceProxyBindings(void* m); #endif diff --git a/src/bindings/bnd_texture.h b/src/bindings/bnd_texture.h index cf6fb08b..74ac3e07 100644 --- a/src/bindings/bnd_texture.h +++ b/src/bindings/bnd_texture.h @@ -4,8 +4,16 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -void initEnvironmentBindings(pybind11::module& m); -void initTextureBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initEnvironmentBindings(py::module_& m); +void initTextureBindings(py::module_& m); +#else +namespace py = pybind11; +void initEnvironmentBindings(py::module& m); +void initTextureBindings(py::module& m); +#endif + #else void initEnvironmentBindings(void* m); void initTextureBindings(void* m); diff --git a/src/bindings/bnd_texture_mapping.h b/src/bindings/bnd_texture_mapping.h index 671d9aca..1b1d92bc 100644 --- a/src/bindings/bnd_texture_mapping.h +++ b/src/bindings/bnd_texture_mapping.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initTextureMappingBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initTextureMappingBindings(py::module_& m); +#else +namespace py = pybind11; +void initTextureMappingBindings(py::module& m); +#endif + #else void initTextureMappingBindings(void* m); #endif diff --git a/src/bindings/bnd_uuid.h b/src/bindings/bnd_uuid.h index e5339558..6a0acb6f 100644 --- a/src/bindings/bnd_uuid.h +++ b/src/bindings/bnd_uuid.h @@ -3,7 +3,12 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -typedef pybind11::object BND_UUID; +#if defined(NANOBIND) +namespace py = nanobind; +#else +namespace py = pybind11; +#endif +typedef py::object BND_UUID; #else typedef std::string BND_UUID; #endif diff --git a/src/bindings/bnd_viewport.h b/src/bindings/bnd_viewport.h index b17f57f2..2491cfe8 100644 --- a/src/bindings/bnd_viewport.h +++ b/src/bindings/bnd_viewport.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initViewportBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initViewportBindings(py::module_& m); +#else +namespace py = pybind11; +void initViewportBindings(py::module& m); +#endif + #else void initViewportBindings(void* m); #endif diff --git a/src/bindings/bnd_xform.h b/src/bindings/bnd_xform.h index 772882ce..00b22401 100644 --- a/src/bindings/bnd_xform.h +++ b/src/bindings/bnd_xform.h @@ -3,7 +3,14 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -void initXformBindings(pybind11::module& m); +#if defined(NANOBIND) +namespace py = nanobind; +void initXformBindings(py::module_& m); +#else +namespace py = pybind11; +void initXformBindings(py::module& m); +#endif + #else void initXformBindings(void* m); #endif diff --git a/src/lib/nanobind b/src/lib/nanobind new file mode 160000 index 00000000..cbf064b9 --- /dev/null +++ b/src/lib/nanobind @@ -0,0 +1 @@ +Subproject commit cbf064b920c47d22eb8e8295bde6ed693c895e05 From 11355880f93acbee1b91ffddead30b3463fbb282 Mon Sep 17 00:00:00 2001 From: fraguada Date: Thu, 1 Aug 2024 13:38:33 +0200 Subject: [PATCH 03/27] js ctor for ViewInfo --- src/bindings/bnd_3dm_settings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bindings/bnd_3dm_settings.cpp b/src/bindings/bnd_3dm_settings.cpp index b7f86b2d..1fb5c9b4 100644 --- a/src/bindings/bnd_3dm_settings.cpp +++ b/src/bindings/bnd_3dm_settings.cpp @@ -234,6 +234,7 @@ void init3dmSettingsBindings(void*) ; class_("ViewInfo") + .constructor<>() .property("name", &BND_ViewInfo::GetName, &BND_ViewInfo::SetName) .property("wallpaperName", &BND_ViewInfo::GetWallpaperFilename) .property("showWallpaperInGrayScale", &BND_ViewInfo::ShowWallpaperInGrayScale, &BND_ViewInfo::SetShowWallpaperInGrayScale) From 68b966f12ddfa7ff4fbe66f0ff97755e3c4ad8b1 Mon Sep 17 00:00:00 2001 From: fraguada Date: Mon, 5 Aug 2024 15:08:41 +0200 Subject: [PATCH 04/27] more nanobind work still fails to compile due to cast, tuples, dicts, etc --- src/bindings/bindings.cpp | 9 +-- src/bindings/bindings.h | 24 +++---- src/bindings/bnd_3dm_attributes.cpp | 5 +- src/bindings/bnd_3dm_settings.cpp | 5 +- src/bindings/bnd_annotationbase.cpp | 22 +++++-- src/bindings/bnd_arc.cpp | 7 +- src/bindings/bnd_arccurve.cpp | 8 ++- src/bindings/bnd_beam.cpp | 5 +- src/bindings/bnd_bezier.cpp | 7 +- src/bindings/bnd_bitmap.cpp | 7 +- src/bindings/bnd_boundingbox.cpp | 32 ++++++--- src/bindings/bnd_box.cpp | 7 +- src/bindings/bnd_brep.cpp | 23 +++++-- src/bindings/bnd_circle.cpp | 7 +- src/bindings/bnd_color.cpp | 8 +++ src/bindings/bnd_cone.cpp | 7 +- src/bindings/bnd_curve.cpp | 7 +- src/bindings/bnd_curveproxy.cpp | 7 +- src/bindings/bnd_cylinder.cpp | 7 +- src/bindings/bnd_decals.cpp | 7 +- src/bindings/bnd_defines.cpp | 4 +- src/bindings/bnd_dimensionstyle.cpp | 8 ++- src/bindings/bnd_dithering.cpp | 7 +- src/bindings/bnd_draco.cpp | 7 +- src/bindings/bnd_ellipse.cpp | 3 +- src/bindings/bnd_embedded_file.cpp | 7 +- src/bindings/bnd_extensions.cpp | 7 +- src/bindings/bnd_file_utilities.cpp | 7 +- src/bindings/bnd_font.cpp | 7 +- src/bindings/bnd_geometry.cpp | 8 ++- src/bindings/bnd_ground_plane.cpp | 7 +- src/bindings/bnd_group.cpp | 7 +- src/bindings/bnd_hatch.cpp | 7 +- src/bindings/bnd_instance.cpp | 7 +- src/bindings/bnd_layer.cpp | 7 +- src/bindings/bnd_light.cpp | 7 +- src/bindings/bnd_linear_workflow.cpp | 7 +- src/bindings/bnd_linecurve.cpp | 7 +- src/bindings/bnd_linetype.cpp | 8 ++- src/bindings/bnd_material.cpp | 7 +- src/bindings/bnd_mesh.cpp | 7 +- src/bindings/bnd_mesh_modifiers.cpp | 7 +- src/bindings/bnd_model_component.cpp | 7 +- src/bindings/bnd_nurbscurve.cpp | 7 +- src/bindings/bnd_nurbssurface.cpp | 7 +- src/bindings/bnd_object.cpp | 7 +- src/bindings/bnd_plane.cpp | 7 +- src/bindings/bnd_planesurface.cpp | 7 +- src/bindings/bnd_point.cpp | 15 ++++- src/bindings/bnd_pointcloud.cpp | 7 +- src/bindings/bnd_pointgeometry.cpp | 7 +- src/bindings/bnd_pointgrid.cpp | 7 +- src/bindings/bnd_polycurve.cpp | 7 +- src/bindings/bnd_polyline.cpp | 7 +- src/bindings/bnd_polylinecurve.cpp | 7 +- src/bindings/bnd_post_effects.cpp | 7 +- src/bindings/bnd_render_channels.cpp | 7 +- src/bindings/bnd_render_content.cpp | 7 +- src/bindings/bnd_render_environments.cpp | 7 +- src/bindings/bnd_revsurface.cpp | 7 +- src/bindings/bnd_rtree.cpp | 7 +- src/bindings/bnd_safe_frame.cpp | 7 +- src/bindings/bnd_skylight.cpp | 7 +- src/bindings/bnd_sphere.cpp | 7 +- src/bindings/bnd_subd.cpp | 7 +- src/bindings/bnd_sun.cpp | 7 +- src/bindings/bnd_surface.cpp | 7 +- src/bindings/bnd_surfaceproxy.cpp | 7 +- src/bindings/bnd_texture.cpp | 7 +- src/bindings/bnd_texture_mapping.cpp | 7 +- src/bindings/bnd_uuid.cpp | 5 ++ src/bindings/bnd_viewport.cpp | 19 ++++-- src/bindings/bnd_xform.cpp | 7 +- tests/cpp/CMakeLists.txt | 49 ++++++++++++++ tests/cpp/ontest_view.cpp | 76 ++++++++++++++++++++++ tests/dotnet/file3dm.ViewTable.cs | 72 ++++++++++++++++++++ tests/javascript/file3dm.ViewTable.test.js | 57 ++++++++++++++++ tests/python/test_File3dm_ViewTable.py | 47 +++++++++++++ 78 files changed, 777 insertions(+), 120 deletions(-) create mode 100644 tests/cpp/CMakeLists.txt create mode 100644 tests/cpp/ontest_view.cpp create mode 100644 tests/dotnet/file3dm.ViewTable.cs create mode 100644 tests/javascript/file3dm.ViewTable.test.js create mode 100644 tests/python/test_File3dm_ViewTable.py diff --git a/src/bindings/bindings.cpp b/src/bindings/bindings.cpp index 08cb1257..c8b3aa88 100644 --- a/src/bindings/bindings.cpp +++ b/src/bindings/bindings.cpp @@ -98,16 +98,11 @@ EMSCRIPTEN_BINDINGS(rhino3dm) { BND_TUPLE CreateTuple(int count) { #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) - nanobind::tuple rc(count); -#else - pybind11::tuple rc(count); - return rc; -#endif + py::tuple rc(count); #else emscripten::val rc(emscripten::val::array()); - return rc; #endif + return rc; } BND_TUPLE NullTuple() diff --git a/src/bindings/bindings.h b/src/bindings/bindings.h index 5beed271..7da9b5ea 100644 --- a/src/bindings/bindings.h +++ b/src/bindings/bindings.h @@ -13,9 +13,12 @@ #if defined(ON_PYTHON_COMPILE) #if defined(NANOBIND) + namespace py = nanobind; #include #include + #include #else + namespace py = pybind11; #include #include #endif @@ -30,22 +33,13 @@ #endif #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) - -typedef nanobind::dict BND_DICT; -typedef nanobind::tuple BND_Color; -typedef nanobind::tuple BND_Color4f; -typedef nanobind::tuple BND_TUPLE; -typedef nanobind::handle BND_DateTime; - -#else -typedef pybind11::dict BND_DICT; -typedef pybind11::tuple BND_Color; -typedef pybind11::tuple BND_Color4f; -typedef pybind11::tuple BND_TUPLE; -typedef pybind11::handle BND_DateTime; -#endif +typedef py::dict BND_DICT; +typedef py::tuple BND_Color; +typedef py::tuple BND_Color4f; +typedef py::tuple BND_TUPLE; +typedef py::handle BND_DateTime; #endif + #if defined(ON_WASM_COMPILE) typedef emscripten::val BND_DICT; typedef emscripten::val BND_Color; diff --git a/src/bindings/bnd_3dm_attributes.cpp b/src/bindings/bnd_3dm_attributes.cpp index bf246256..ef98409d 100644 --- a/src/bindings/bnd_3dm_attributes.cpp +++ b/src/bindings/bnd_3dm_attributes.cpp @@ -111,11 +111,11 @@ BND_TUPLE BND_3dmObjectAttributes::GetGroupList() const #if defined(ON_PYTHON_COMPILE) #if defined(NANOBIND) namespace py = nanobind; -void init3dmAttributesBindings(py::module_& m) +void init3dmAttributesBindings(py::module_& m){} #else namespace py = pybind11; void init3dmAttributesBindings(py::module& m) -#endif + { py::class_(m, "ObjectAttributes") .def(py::init<>()) @@ -156,6 +156,7 @@ void init3dmAttributesBindings(py::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_3dm_settings.cpp b/src/bindings/bnd_3dm_settings.cpp index 78deb932..ef100080 100644 --- a/src/bindings/bnd_3dm_settings.cpp +++ b/src/bindings/bnd_3dm_settings.cpp @@ -124,11 +124,11 @@ void BND_File3dmSettings::SetEarthAnchorPoint(const BND_EarthAnchorPoint& anchor #if defined(ON_PYTHON_COMPILE) #if defined(NANOBIND) namespace py = nanobind; -void init3dmSettingsBindings(py::module_& m) +void init3dmSettingsBindings(py::module_& m){} #else namespace py = pybind11; void init3dmSettingsBindings(py::module& m) -#endif + { py::class_(m, "ConstructionPlane") .def(py::init<>()) @@ -221,6 +221,7 @@ void init3dmSettingsBindings(py::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_annotationbase.cpp b/src/bindings/bnd_annotationbase.cpp index b0313cb1..c1dbaf9f 100644 --- a/src/bindings/bnd_annotationbase.cpp +++ b/src/bindings/bnd_annotationbase.cpp @@ -1,5 +1,11 @@ #include "bindings.h" +#if defined(NANOBIND) +namespace py = nanobind; +#else +namespace py = pybind11; +#endif + BND_AnnotationBase::BND_AnnotationBase() { } @@ -268,7 +274,7 @@ BND_DICT BND_DimLinear::GetPoints() const return d; } #if defined(ON_PYTHON_COMPILE) - throw pybind11::value_error("Failed to get DimLinear points"); + throw py::value_error("Failed to get DimLinear points"); #else return emscripten::val::null(); #endif @@ -369,7 +375,7 @@ BND_DICT BND_DimAngular::GetPoints() const return d; } #if defined(ON_PYTHON_COMPILE) - throw pybind11::value_error("Failed to get DimAngular points"); + throw py::value_error("Failed to get DimAngular points"); #else return emscripten::val::null(); #endif @@ -463,7 +469,7 @@ BND_DICT BND_DimRadial::GetPoints() const return d; } #if defined(ON_PYTHON_COMPILE) - throw pybind11::value_error("Failed to get DimRadial points"); + throw py::value_error("Failed to get DimRadial points"); #else return emscripten::val::null(); #endif @@ -550,7 +556,7 @@ BND_DICT BND_DimOrdinate::GetPoints() const return d; } #if defined(ON_PYTHON_COMPILE) - throw pybind11::value_error("Failed to get DimOrdinate points"); + throw py::value_error("Failed to get DimOrdinate points"); #else return emscripten::val::null(); #endif @@ -623,8 +629,11 @@ std::vector BND_Centermark::GetDisplayLines(const BND_DimensionStyle& d } #if defined(ON_PYTHON_COMPILE) -namespace py = pybind11; -void initAnnotationBaseBindings(pybind11::module& m) + +#if defined(NANOBIND) +void initAnnotationBaseBindings(py::module_& m){} +#else +void initAnnotationBaseBindings(py::module& m) { py::class_(m, "AnnotationBase") .def_property_readonly("DimensionStyleId", &BND_AnnotationBase::DimensionStyleId) @@ -682,6 +691,7 @@ void initAnnotationBaseBindings(pybind11::module& m) } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_arc.cpp b/src/bindings/bnd_arc.cpp index 5acd82cb..0158bdb8 100644 --- a/src/bindings/bnd_arc.cpp +++ b/src/bindings/bnd_arc.cpp @@ -124,12 +124,14 @@ BND_NurbsCurve* BND_Arc::ToNurbsCurve() const } #if defined(ON_PYTHON_COMPILE) + +#if defined(NANOBIND) namespace py = nanobind; -void initArcBindings(py::module_& m) +void initArcBindings(py::module_& m){} #else namespace py = pybind11; void initArcBindings(py::module& m) -#endif + { py::class_(m, "Arc") .def(py::init(), py::arg("circle"), py::arg("angleRadians")) @@ -165,6 +167,7 @@ void initArcBindings(py::module& m) .def("ToNurbsCurve", &BND_Arc::ToNurbsCurve); } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_arccurve.cpp b/src/bindings/bnd_arccurve.cpp index d1cd496f..ba04af70 100644 --- a/src/bindings/bnd_arccurve.cpp +++ b/src/bindings/bnd_arccurve.cpp @@ -50,8 +50,13 @@ void BND_ArcCurve::SetTrackedPointer(ON_ArcCurve* arccurve, const ON_ModelCompon #if defined(ON_PYTHON_COMPILE) + +#if defined(NANOBIND) +namespace py = nanobind; +void initArcCurveBindings(py::module_& m){} +#else namespace py = pybind11; -void initArcCurveBindings(pybind11::module& m) +void initArcCurveBindings(py::module& m) { py::class_(m, "ArcCurve") .def_static("CreateFromArc", &BND_ArcCurve::CreateFromArc, py::arg("arc")) @@ -68,6 +73,7 @@ void initArcCurveBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_beam.cpp b/src/bindings/bnd_beam.cpp index 35248b3e..100a07a8 100644 --- a/src/bindings/bnd_beam.cpp +++ b/src/bindings/bnd_beam.cpp @@ -194,11 +194,11 @@ BND_Extrusion::BND_Extrusion(ON_Extrusion* extrusion, const ON_ModelComponentRef #if defined(ON_PYTHON_COMPILE) #if defined(NANOBIND) namespace py = nanobind; -void initExtrusionBindings(py::module_& m) +void initExtrusionBindings(py::module_& m){} #else namespace py = pybind11; void initExtrusionBindings(py::module& m) -#endif + { py::class_(m, "Extrusion") .def_static("Create", &BND_Extrusion::Create, py::arg("planarCurve"), py::arg("height"), py::arg("cap")) @@ -236,6 +236,7 @@ void initExtrusionBindings(py::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_bezier.cpp b/src/bindings/bnd_bezier.cpp index b439ddb9..d5480d64 100644 --- a/src/bindings/bnd_bezier.cpp +++ b/src/bindings/bnd_bezier.cpp @@ -32,8 +32,12 @@ BND_TUPLE BND_BezierCurve::Split(double t) #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initBezierBindings(py::module_& m){} +#else namespace py = pybind11; -void initBezierBindings(pybind11::module& m) +void initBezierBindings(py::module& m) { py::class_(m, "BezierCurve") .def_property_readonly("Dimension", &BND_BezierCurve::Dimension) @@ -52,6 +56,7 @@ void initBezierBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_bitmap.cpp b/src/bindings/bnd_bitmap.cpp index 7d61f7d5..ac132475 100644 --- a/src/bindings/bnd_bitmap.cpp +++ b/src/bindings/bnd_bitmap.cpp @@ -17,8 +17,12 @@ void BND_Bitmap::SetTrackedPointer(ON_Bitmap* bitmap, const ON_ModelComponentRef #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initBitmapBindings(py::module_& m){} +#else namespace py = pybind11; -void initBitmapBindings(pybind11::module& m) +void initBitmapBindings(py::module& m) { py::class_(m, "Bitmap") .def(py::init<>()) @@ -30,6 +34,7 @@ void initBitmapBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_boundingbox.cpp b/src/bindings/bnd_boundingbox.cpp index 31c58587..bb8cb1c3 100644 --- a/src/bindings/bnd_boundingbox.cpp +++ b/src/bindings/bnd_boundingbox.cpp @@ -1,5 +1,11 @@ #include "bindings.h" +#if defined(NANOBIND) +namespace py = nanobind; +#else +namespace py = pybind11; +#endif + BND_BoundingBox::BND_BoundingBox(const ON_3dPoint& min, const ON_3dPoint& max) : m_bbox(min, max) { @@ -90,25 +96,30 @@ BND_BoundingBox BND_BoundingBox::Union(const BND_BoundingBox& a, const BND_Bound #if defined(ON_PYTHON_COMPILE) -pybind11::dict BND_BoundingBox::Encode() const +py::dict BND_BoundingBox::Encode() const { - pybind11::dict d; + py::dict d; d["Min"] = PointToDict(m_bbox.m_min); d["Max"] = PointToDict(m_bbox.m_max); return d; } -BND_BoundingBox* BND_BoundingBox::Decode(pybind11::dict jsonObject) +#if defined(NANOBIND) +// TODO: BND_BoundingBox::Decode for NANOBIND +#else +BND_BoundingBox* BND_BoundingBox::Decode(py::dict jsonObject) { ON_BoundingBox bbox; - pybind11::dict d = jsonObject["Min"].cast(); + py::dict d = jsonObject["Min"].cast(); bbox.m_min = PointFromDict(d); - d = jsonObject["Max"].cast(); + d = jsonObject["Max"].cast(); bbox.m_max = PointFromDict(d); return new BND_BoundingBox(bbox); } #endif +#endif + #if defined(ON_WASM_COMPILE) emscripten::val BND_BoundingBox::Encode() const { @@ -150,8 +161,10 @@ BND_BoundingBox* BND_BoundingBox::Decode(emscripten::val jsonObject) #if defined(ON_PYTHON_COMPILE) -namespace py = pybind11; -void initBoundingBoxBindings(pybind11::module& m) +#if defined(NANOBIND) +void initBoundingBoxBindings(py::module_& m){} +#else +void initBoundingBoxBindings(py::module& m) { py::class_(m, "BoundingBox") .def(py::init(), py::arg("minPoint"), py::arg("maxPoint")) @@ -175,7 +188,10 @@ void initBoundingBoxBindings(pybind11::module& m) .def_static("Decode", &BND_BoundingBox::Decode, py::arg("jsonObject")) ; } -#else +#endif +#endif + +#if defined(ON_WASM_COMPILE) using namespace emscripten; void initBoundingBoxBindings(void*) diff --git a/src/bindings/bnd_box.cpp b/src/bindings/bnd_box.cpp index 9ef325ab..7a43ee0a 100644 --- a/src/bindings/bnd_box.cpp +++ b/src/bindings/bnd_box.cpp @@ -29,8 +29,12 @@ ON_3dPoint BND_Box::PointAt(double x, double y, double z) const //} #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initBoxBindings(py::module_& m){} +#else namespace py = pybind11; -void initBoxBindings(pybind11::module& m) +void initBoxBindings(py::module& m) { py::class_(m, "Box") .def(py::init(), py::arg("bbox")) @@ -44,6 +48,7 @@ void initBoxBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_brep.cpp b/src/bindings/bnd_brep.cpp index a0ee034e..995b321c 100644 --- a/src/bindings/bnd_brep.cpp +++ b/src/bindings/bnd_brep.cpp @@ -1,5 +1,13 @@ #include "bindings.h" +#if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +#else +namespace py = pybind11; +#endif +#endif + BND_BrepEdge::BND_BrepEdge(ON_BrepEdge* edge, const ON_ModelComponentReference* compref) { m_edge = edge; @@ -186,7 +194,7 @@ BND_BrepFace* BND_BrepFaceList::GetFace(int i) { #if defined(ON_PYTHON_COMPILE) if (i >= Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif ON_BrepFace* face = m_brep->Face(i); @@ -297,7 +305,7 @@ BND_Surface* BND_BrepSurfaceList::GetSurface(int i) { #if defined(ON_PYTHON_COMPILE) if (i >= Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif ON_Surface* surface = nullptr; @@ -320,7 +328,7 @@ BND_BrepEdge* BND_BrepEdgeList::GetEdge(int i) { #if defined(ON_PYTHON_COMPILE) if (i >= Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif ON_BrepEdge* edge = m_brep->Edge(i); @@ -352,7 +360,7 @@ BND_BrepVertex* BND_BrepVertexList::GetVertex(int i) { #if defined(ON_PYTHON_COMPILE) if (i >= Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif ON_BrepVertex* vertex = m_brep->Vertex(i); @@ -376,8 +384,10 @@ BND_TUPLE BND_BrepVertex::EdgeIndices() const { ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -namespace py = pybind11; -void initBrepBindings(pybind11::module& m) +#if defined(NANOBIND) +void initBrepBindings(py::module_& m){} +#else +void initBrepBindings(py::module& m) { py::class_(m, "BrepEdge") ; @@ -442,6 +452,7 @@ void initBrepBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_circle.cpp b/src/bindings/bnd_circle.cpp index ea4eefab..3adef6e7 100644 --- a/src/bindings/bnd_circle.cpp +++ b/src/bindings/bnd_circle.cpp @@ -95,8 +95,12 @@ BND_DICT BND_Circle::Encode() const #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initCircleBindings(py::module_& m){} +#else namespace py = pybind11; -void initCircleBindings(pybind11::module& m) +void initCircleBindings(py::module& m) { py::class_(m, "Circle") .def(py::init(), py::arg("radius")) @@ -123,6 +127,7 @@ void initCircleBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_color.cpp b/src/bindings/bnd_color.cpp index 53f89c37..14d5245c 100644 --- a/src/bindings/bnd_color.cpp +++ b/src/bindings/bnd_color.cpp @@ -13,6 +13,9 @@ BND_Color ON_Color_to_Binding(const ON_Color& color) return py::make_tuple(color.Red(), color.Green(), color.Blue(), 255 - color.Alpha()); } +#if defined(NANOBIND) +// TODO: Binding_to_ON_Color is not implemented in nanobind +#else ON_Color Binding_to_ON_Color(const BND_Color& color) { int r = color[0].cast(); @@ -21,12 +24,16 @@ ON_Color Binding_to_ON_Color(const BND_Color& color) int a = color[3].cast(); return ON_Color(r, g, b, 255-a); } +#endif BND_Color4f ON_4fColor_to_Binding(const ON_4fColor& color) { return py::make_tuple(color.Red(), color.Green(), color.Blue(), color.Alpha()); } +#if defined(NANOBIND) +// TODO: Binding_to_ON_4fColor is not implemented in nanobind +#else ON_4fColor Binding_to_ON_4fColor(const BND_Color4f& color) { float r = color[0].cast(); @@ -35,6 +42,7 @@ ON_4fColor Binding_to_ON_4fColor(const BND_Color4f& color) float a = color[3].cast(); return ON_4fColor(r, g, b, a); } +#endif #endif diff --git a/src/bindings/bnd_cone.cpp b/src/bindings/bnd_cone.cpp index 50ef01b7..df638606 100644 --- a/src/bindings/bnd_cone.cpp +++ b/src/bindings/bnd_cone.cpp @@ -20,8 +20,12 @@ BND_Brep* BND_Cone::ToBrep(bool capBottom) const } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initConeBindings(py::module_& m){} +#else namespace py = pybind11; -void initConeBindings(pybind11::module& m) +void initConeBindings(py::module& m) { py::class_(m, "Cone") .def_property("Height", &BND_Cone::GetHeight, &BND_Cone::SetHeight) @@ -37,6 +41,7 @@ void initConeBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_curve.cpp b/src/bindings/bnd_curve.cpp index 4d894ade..5aa7c82e 100644 --- a/src/bindings/bnd_curve.cpp +++ b/src/bindings/bnd_curve.cpp @@ -252,8 +252,12 @@ BND_NurbsCurve* BND_Curve::ToNurbsCurve2(BND_Interval subdomain) const #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initCurveBindings(py::module_& m){} +#else namespace py = pybind11; -void initCurveBindings(pybind11::module& m) +void initCurveBindings(py::module& m) { py::enum_(m, "CurveEvaluationSide") .value("Default", CurveEvaluationSide::Default) @@ -356,6 +360,7 @@ void initCurveBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_curveproxy.cpp b/src/bindings/bnd_curveproxy.cpp index 6dc1d529..29578f54 100644 --- a/src/bindings/bnd_curveproxy.cpp +++ b/src/bindings/bnd_curveproxy.cpp @@ -14,14 +14,19 @@ void BND_CurveProxy::SetTrackedPointer(ON_CurveProxy* curveproxy, const ON_Model ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initCurveProxyBindings(py::module_& m){} +#else namespace py = pybind11; -void initCurveProxyBindings(pybind11::module& m) +void initCurveProxyBindings(py::module& m) { py::class_(m, "CurveProxy") .def_property_readonly("ProxyCurveIsReversed", &BND_CurveProxy::ProxyCurveIsReversed) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_cylinder.cpp b/src/bindings/bnd_cylinder.cpp index 91764287..16238d4e 100644 --- a/src/bindings/bnd_cylinder.cpp +++ b/src/bindings/bnd_cylinder.cpp @@ -42,8 +42,12 @@ BND_NurbsSurface* BND_Cylinder::ToNurbsSurface() const #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initCylinderBindings(py::module_& m){} +#else namespace py = pybind11; -void initCylinderBindings(pybind11::module& m) +void initCylinderBindings(py::module& m) { py::class_(m, "Cylinder") .def(py::init(), py::arg("baseCircle")) @@ -62,6 +66,7 @@ void initCylinderBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_decals.cpp b/src/bindings/bnd_decals.cpp index 39cd4dbb..28bf96e2 100644 --- a/src/bindings/bnd_decals.cpp +++ b/src/bindings/bnd_decals.cpp @@ -279,8 +279,12 @@ BND_File3dmDecal* BND_File3dmDecalTable::IterIndex(int index) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initDecalBindings(py::module_& m){} +#else namespace py = pybind11; -void initDecalBindings(pybind11::module& m) +void initDecalBindings(py::module& m) { py::enum_(m, "Mappings") .value("None", Mappings::None) @@ -321,6 +325,7 @@ void initDecalBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_defines.cpp b/src/bindings/bnd_defines.cpp index fb14a52b..11afb61f 100644 --- a/src/bindings/bnd_defines.cpp +++ b/src/bindings/bnd_defines.cpp @@ -31,9 +31,9 @@ static std::vector ArrowPoints(ON_Arrowhead::arrow_type arrowType, d #if defined(ON_PYTHON_COMPILE) #if defined(NANOBIND) namespace py = nanobind; +void initDefines(py::module_& m){} #else namespace py = pybind11; -#endif void initDefines(py::module& m) { py::enum_(m, "ComponentIndexType") @@ -373,7 +373,7 @@ ON_Plane PlaneFromDict(py::dict& dict) plane.UpdateEquation(); return plane; } - +#endif #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_dimensionstyle.cpp b/src/bindings/bnd_dimensionstyle.cpp index 663542b4..de25b42d 100644 --- a/src/bindings/bnd_dimensionstyle.cpp +++ b/src/bindings/bnd_dimensionstyle.cpp @@ -45,8 +45,12 @@ ON_Arrowhead::arrow_type BND_DimensionStyle::LeaderArrowType() const #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initDimensionStyleBindings(py::module_& m){} +#else namespace py = pybind11; -void initDimensionStyleBindings(pybind11::module& m) +void initDimensionStyleBindings(py::module& m) { py::class_ pyDimStyle(m, "DimensionStyle"); @@ -208,6 +212,8 @@ void initDimensionStyleBindings(pybind11::module& m) ; } #endif +#endif + #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_dithering.cpp b/src/bindings/bnd_dithering.cpp index 254b8748..cc8465c7 100644 --- a/src/bindings/bnd_dithering.cpp +++ b/src/bindings/bnd_dithering.cpp @@ -33,8 +33,12 @@ BND_File3dmDithering::BND_File3dmDithering(ON_Dithering* dit) } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initDitheringBindings(py::module_& m){} +#else namespace py = pybind11; -void initDitheringBindings(pybind11::module& m) +void initDitheringBindings(py::module& m) { py::class_(m, "Dithering") .def(py::init<>()) @@ -44,6 +48,7 @@ void initDitheringBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_draco.cpp b/src/bindings/bnd_draco.cpp index 2ac45cd7..4bb61e62 100644 --- a/src/bindings/bnd_draco.cpp +++ b/src/bindings/bnd_draco.cpp @@ -401,8 +401,12 @@ std::string BND_Draco::ToBase64String() const #endif #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initDracoBindings(py::module_& m){} +#else namespace py = pybind11; -void initDracoBindings(pybind11::module& m) +void initDracoBindings(py::module& m) { #if defined(ON_INCLUDE_DRACO) py::class_(m, "DracoCompressionOptions") @@ -430,6 +434,7 @@ void initDracoBindings(pybind11::module& m) #endif } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_ellipse.cpp b/src/bindings/bnd_ellipse.cpp index eb3d369c..e498a94c 100644 --- a/src/bindings/bnd_ellipse.cpp +++ b/src/bindings/bnd_ellipse.cpp @@ -4,15 +4,16 @@ #if defined(ON_PYTHON_COMPILE) #if defined(NANOBIND) namespace py = nanobind; +void initEllipseBindings(py::module_& m){} #else namespace py = pybind11; -#endif void initEllipseBindings(py::module& m) { py::class_(m, "Ellipse") ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_embedded_file.cpp b/src/bindings/bnd_embedded_file.cpp index 158956e5..fa0d24b5 100644 --- a/src/bindings/bnd_embedded_file.cpp +++ b/src/bindings/bnd_embedded_file.cpp @@ -111,8 +111,12 @@ BND_File3dmEmbeddedFile* BND_File3dmEmbeddedFileTable::FindId(BND_UUID id) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initEmbeddedFileBindings(py::module_& m){} +#else namespace py = pybind11; -void initEmbeddedFileBindings(pybind11::module& m) +void initEmbeddedFileBindings(py::module& m) { py::class_(m, "EmbeddedFile") .def(py::init<>()) @@ -125,6 +129,7 @@ void initEmbeddedFileBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_extensions.cpp b/src/bindings/bnd_extensions.cpp index 8d8ed924..39858572 100644 --- a/src/bindings/bnd_extensions.cpp +++ b/src/bindings/bnd_extensions.cpp @@ -1647,8 +1647,12 @@ struct PyBNDIterator { #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initExtensionsBindings(py::module_& m){} +#else namespace py = pybind11; -void initExtensionsBindings(pybind11::module& m) +void initExtensionsBindings(py::module& m) { py::class_(m, "File3dmPlugInData") ; @@ -1974,6 +1978,7 @@ void initExtensionsBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_file_utilities.cpp b/src/bindings/bnd_file_utilities.cpp index ff311730..61b11de2 100644 --- a/src/bindings/bnd_file_utilities.cpp +++ b/src/bindings/bnd_file_utilities.cpp @@ -20,8 +20,12 @@ BND_FileReference BND_FileReference::CreateFromFullAndRelativePaths(std::wstring ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initFileUtilitiesBindings(py::module_& m){} +#else namespace py = pybind11; -void initFileUtilitiesBindings(pybind11::module& m) +void initFileUtilitiesBindings(py::module& m) { py::class_(m, "FileReference") .def_static("CreateFromFullPath", &BND_FileReference::CreateFromFullPath, py::arg("path")) @@ -31,6 +35,7 @@ void initFileUtilitiesBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_font.cpp b/src/bindings/bnd_font.cpp index c0421ea1..ba20850e 100644 --- a/src/bindings/bnd_font.cpp +++ b/src/bindings/bnd_font.cpp @@ -21,8 +21,12 @@ BND_Font::BND_Font(std::wstring familyName) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initFontBindings(py::module_& m){} +#else namespace py = pybind11; -void initFontBindings(pybind11::module& m) +void initFontBindings(py::module& m) { py::class_(m, "Font") .def(py::init(), py::arg("familyName")) @@ -43,6 +47,7 @@ void initFontBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_geometry.cpp b/src/bindings/bnd_geometry.cpp index f6a9d6e3..1c27a13d 100644 --- a/src/bindings/bnd_geometry.cpp +++ b/src/bindings/bnd_geometry.cpp @@ -33,8 +33,12 @@ bool BND_GeometryBase::Rotate(double rotation_angle, const ON_3dVector& rotation #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initGeometryBindings(py::module_& m){} +#else namespace py = pybind11; -void initGeometryBindings(pybind11::module& m) +void initGeometryBindings(py::module& m) { py::class_(m, "GeometryBase") .def_property_readonly("ObjectType", &BND_GeometryBase::ObjectType) @@ -50,6 +54,8 @@ void initGeometryBindings(pybind11::module& m) ; } #endif +#endif + #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_ground_plane.cpp b/src/bindings/bnd_ground_plane.cpp index 95ef22ad..a8ad6421 100644 --- a/src/bindings/bnd_ground_plane.cpp +++ b/src/bindings/bnd_ground_plane.cpp @@ -42,8 +42,12 @@ BND_File3dmGroundPlane::BND_File3dmGroundPlane(ON_GroundPlane* gp) } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initGroundPlaneBindings(py::module_& m){} +#else namespace py = pybind11; -void initGroundPlaneBindings(pybind11::module& m) +void initGroundPlaneBindings(py::module& m) { py::class_(m, "GroundPlane") .def(py::init<>()) @@ -62,6 +66,7 @@ void initGroundPlaneBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_group.cpp b/src/bindings/bnd_group.cpp index 58edbf23..dc39b0f7 100644 --- a/src/bindings/bnd_group.cpp +++ b/src/bindings/bnd_group.cpp @@ -20,8 +20,12 @@ void BND_Group::SetTrackedPointer(ON_Group* group, const ON_ModelComponentRefere #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initGroupBindings(py::module_& m){} +#else namespace py = pybind11; -void initGroupBindings(pybind11::module& m) +void initGroupBindings(py::module& m) { py::class_(m, "Group") .def(py::init<>()) @@ -31,6 +35,7 @@ void initGroupBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_hatch.cpp b/src/bindings/bnd_hatch.cpp index b941b506..146fcbdd 100644 --- a/src/bindings/bnd_hatch.cpp +++ b/src/bindings/bnd_hatch.cpp @@ -19,8 +19,12 @@ void BND_Hatch::SetTrackedPointer(ON_Hatch* hatch, const ON_ModelComponentRefere ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initHatchBindings(py::module_& m){} +#else namespace py = pybind11; -void initHatchBindings(pybind11::module& m) +void initHatchBindings(py::module& m) { py::class_(m, "Hatch") .def(py::init<>()) @@ -33,6 +37,7 @@ void initHatchBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_instance.cpp b/src/bindings/bnd_instance.cpp index 6dade61f..f0455894 100644 --- a/src/bindings/bnd_instance.cpp +++ b/src/bindings/bnd_instance.cpp @@ -76,8 +76,12 @@ BND_Transform BND_InstanceReferenceGeometry::Xform() const ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initInstanceBindings(py::module_& m){} +#else namespace py = pybind11; -void initInstanceBindings(pybind11::module& m) +void initInstanceBindings(py::module& m) { py::enum_(m, "InstanceDefinitionUpdateType") .value("Static", InstanceDefinitionUpdateType::Static) @@ -104,6 +108,7 @@ void initInstanceBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_layer.cpp b/src/bindings/bnd_layer.cpp index 444db789..869f45b6 100644 --- a/src/bindings/bnd_layer.cpp +++ b/src/bindings/bnd_layer.cpp @@ -100,8 +100,12 @@ void BND_Layer::SetPlotColor(const BND_Color& color) #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initLayerBindings(py::module_& m){} +#else namespace py = pybind11; -void initLayerBindings(pybind11::module& m) +void initLayerBindings(py::module& m) { py::class_(m, "Layer") .def(py::init<>()) @@ -134,6 +138,7 @@ void initLayerBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_light.cpp b/src/bindings/bnd_light.cpp index 76de0a75..77f6cdaf 100644 --- a/src/bindings/bnd_light.cpp +++ b/src/bindings/bnd_light.cpp @@ -32,8 +32,12 @@ BND_TUPLE BND_Light::GetSpotLightRadii() const #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initLightBindings(py::module_& m){} +#else namespace py = pybind11; -void initLightBindings(pybind11::module& m) +void initLightBindings(py::module& m) { py::class_(m, "Light") .def(py::init<>()) @@ -68,6 +72,7 @@ void initLightBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_linear_workflow.cpp b/src/bindings/bnd_linear_workflow.cpp index 8c6bb56d..19f21c52 100644 --- a/src/bindings/bnd_linear_workflow.cpp +++ b/src/bindings/bnd_linear_workflow.cpp @@ -32,8 +32,12 @@ BND_File3dmLinearWorkflow::BND_File3dmLinearWorkflow(ON_LinearWorkflow* lw) } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initLinearWorkflowBindings(py::module_& m){} +#else namespace py = pybind11; -void initLinearWorkflowBindings(pybind11::module& m) +void initLinearWorkflowBindings(py::module& m) { py::class_(m, "LinearWorkflow") .def(py::init<>()) @@ -47,6 +51,7 @@ void initLinearWorkflowBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_linecurve.cpp b/src/bindings/bnd_linecurve.cpp index e9c19cae..1f411b83 100644 --- a/src/bindings/bnd_linecurve.cpp +++ b/src/bindings/bnd_linecurve.cpp @@ -24,8 +24,12 @@ void BND_LineCurve::SetTrackedPointer(ON_LineCurve* linecurve, const ON_ModelCom #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initLineCurveBindings(py::module_& m){} +#else namespace py = pybind11; -void initLineCurveBindings(pybind11::module& m) +void initLineCurveBindings(py::module& m) { py::class_(m, "LineCurve") .def(py::init(), py::arg("start"), py::arg("end")) @@ -33,6 +37,7 @@ void initLineCurveBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_linetype.cpp b/src/bindings/bnd_linetype.cpp index 341f8518..5539bf5c 100644 --- a/src/bindings/bnd_linetype.cpp +++ b/src/bindings/bnd_linetype.cpp @@ -52,9 +52,12 @@ int BND_Linetype::AppendSegment(double length, bool isSolid) #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initLinetypeBindings(py::module_& m){} +#else namespace py = pybind11; - -void initLinetypeBindings(pybind11::module& m) +void initLinetypeBindings(py::module& m) { py::class_(m, "Linetype") .def(py::init<>()) @@ -79,6 +82,7 @@ void initLinetypeBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_material.cpp b/src/bindings/bnd_material.cpp index d50ddc7d..328a30a7 100644 --- a/src/bindings/bnd_material.cpp +++ b/src/bindings/bnd_material.cpp @@ -133,8 +133,12 @@ bool BND_PhysicallyBasedMaterial::Supported() const ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initMaterialBindings(py::module_& m){} +#else namespace py = pybind11; -void initMaterialBindings(pybind11::module& m) +void initMaterialBindings(py::module& m) { py::class_(m, "PhysicallyBasedMaterial") .def_property_readonly("Supported", &BND_PhysicallyBasedMaterial::Supported) @@ -201,6 +205,7 @@ void initMaterialBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_mesh.cpp b/src/bindings/bnd_mesh.cpp index d62ebf86..f14f15bf 100644 --- a/src/bindings/bnd_mesh.cpp +++ b/src/bindings/bnd_mesh.cpp @@ -937,8 +937,12 @@ void BND_Mesh::SetCachedTextureCoordinates(class BND_TextureMapping* tm, class B #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initMeshBindings(py::module_& m){} +#else namespace py = pybind11; -void initMeshBindings(pybind11::module& m) +void initMeshBindings(py::module& m) { py::class_(m, "MeshingParameters") .def(py::init<>()) @@ -1081,6 +1085,7 @@ void initMeshBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_mesh_modifiers.cpp b/src/bindings/bnd_mesh_modifiers.cpp index f8da2a90..365e0d3a 100644 --- a/src/bindings/bnd_mesh_modifiers.cpp +++ b/src/bindings/bnd_mesh_modifiers.cpp @@ -188,8 +188,12 @@ BND_File3dmMeshModifiers::BND_File3dmMeshModifiers(const BND_File3dmMeshModifier ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initMeshModifierBindings(py::module_& m){} +#else namespace py = pybind11; -void initMeshModifierBindings(pybind11::module& m) +void initMeshModifierBindings(py::module& m) { py::class_(m, "Displacement") .def(py::init<>()) @@ -266,6 +270,7 @@ void initMeshModifierBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_model_component.cpp b/src/bindings/bnd_model_component.cpp index 34c59787..4318f078 100644 --- a/src/bindings/bnd_model_component.cpp +++ b/src/bindings/bnd_model_component.cpp @@ -22,8 +22,12 @@ void BND_ModelComponent::SetId(BND_UUID id) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initModelComponentBindings(py::module_& m){} +#else namespace py = pybind11; -void initModelComponentBindings(pybind11::module& m) +void initModelComponentBindings(py::module& m) { py::class_(m, "ModelComponent") .def("DataCRC", &BND_ModelComponent::DataCRC, py::arg("currentRemainder")) @@ -33,6 +37,7 @@ void initModelComponentBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_nurbscurve.cpp b/src/bindings/bnd_nurbscurve.cpp index c6e7e0a5..58cd4814 100644 --- a/src/bindings/bnd_nurbscurve.cpp +++ b/src/bindings/bnd_nurbscurve.cpp @@ -222,8 +222,12 @@ BND_BezierCurve* BND_NurbsCurve::ConvertSpanToBezier(int index) const /////////////////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initNurbsCurveBindings(py::module_& m){} +#else namespace py = pybind11; -void initNurbsCurveBindings(pybind11::module& m) +void initNurbsCurveBindings(py::module& m) { py::class_(m, "NurbsCurveKnotList", py::buffer_protocol()) .def("__len__", &BND_NurbsCurveKnotList::Count) @@ -297,6 +301,7 @@ void initNurbsCurveBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_nurbssurface.cpp b/src/bindings/bnd_nurbssurface.cpp index 16edc170..74f42060 100644 --- a/src/bindings/bnd_nurbssurface.cpp +++ b/src/bindings/bnd_nurbssurface.cpp @@ -197,8 +197,12 @@ BND_NurbsSurfacePointList BND_NurbsSurface::Points() #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initNurbsSurfaceBindings(py::module_& m){} +#else namespace py = pybind11; -void initNurbsSurfaceBindings(pybind11::module& m) +void initNurbsSurfaceBindings(py::module& m) { py::class_(m, "NurbsSurfaceKnotList", py::buffer_protocol()) .def("__len__", &BND_NurbsSurfaceKnotList::Count) @@ -272,6 +276,7 @@ void initNurbsSurfaceBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_object.cpp b/src/bindings/bnd_object.cpp index bce001bd..49031736 100644 --- a/src/bindings/bnd_object.cpp +++ b/src/bindings/bnd_object.cpp @@ -1546,8 +1546,12 @@ BND_TUPLE BND_CommonObject::IsValidWithLog() const } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initObjectBindings(py::module_& m){} +#else namespace py = pybind11; -void initObjectBindings(pybind11::module& m) +void initObjectBindings(py::module& m) { py::class_(m, "CommonObject") .def_property_readonly("IsValid", &BND_CommonObject::IsValid) @@ -1568,6 +1572,7 @@ void initObjectBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_plane.cpp b/src/bindings/bnd_plane.cpp index 9a48bcf4..8596379d 100644 --- a/src/bindings/bnd_plane.cpp +++ b/src/bindings/bnd_plane.cpp @@ -190,8 +190,12 @@ BND_Plane BND_PlaneHelper::WorldXY() } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initPlaneBindings(py::module_& m){} +#else namespace py = pybind11; -void initPlaneBindings(pybind11::module& m) +void initPlaneBindings(py::module& m) { py::class_(m, "Plane") .def_static("WorldXY", &BND_Plane::WorldXY) @@ -215,6 +219,7 @@ void initPlaneBindings(pybind11::module& m) ; } #endif +#endif #if defined ON_WASM_COMPILE diff --git a/src/bindings/bnd_planesurface.cpp b/src/bindings/bnd_planesurface.cpp index a389890b..3d8874ec 100644 --- a/src/bindings/bnd_planesurface.cpp +++ b/src/bindings/bnd_planesurface.cpp @@ -30,8 +30,12 @@ BND_PlaneSurface::BND_PlaneSurface(const BND_Plane& plane, const BND_Interval& x ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initPlaneSurfaceBindings(py::module_& m){} +#else namespace py = pybind11; -void initPlaneSurfaceBindings(pybind11::module& m) +void initPlaneSurfaceBindings(py::module& m) { py::class_(m, "PlaneSurface") .def(py::init<>()) @@ -39,6 +43,7 @@ void initPlaneSurfaceBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_point.cpp b/src/bindings/bnd_point.cpp index d3b29e88..da07271a 100644 --- a/src/bindings/bnd_point.cpp +++ b/src/bindings/bnd_point.cpp @@ -1,7 +1,12 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +#else +namespace py = pybind11; #include #endif +#endif BND_Interval::BND_Interval(const ON_Interval& i) @@ -34,6 +39,9 @@ ON_3dPoint BND_Point3d::Transform(const ON_3dPoint& pt, const BND_Transform& tra #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +void initPointBindings(py::module_& m){} +#else static ON_3dPoint GetUnsetPoint3d(pybind11::object /*self*/) { return ON_3dPoint::UnsetPoint; @@ -304,9 +312,7 @@ static std::string ReprInterval(const BND_Interval& i) return repr.str(); } - -namespace py = pybind11; -void initPointBindings(pybind11::module& m) +void initPointBindings(py::module& m) { py::class_(m, "Point2d") .def(py::init(), py::arg("x"), py::arg("y")) @@ -415,7 +421,10 @@ void initPointBindings(pybind11::module& m) .def("__repr__", &ReprInterval); } +#endif + #else + using namespace emscripten; void initPointBindings(void*) diff --git a/src/bindings/bnd_pointcloud.cpp b/src/bindings/bnd_pointcloud.cpp index 461e624b..0e153a14 100644 --- a/src/bindings/bnd_pointcloud.cpp +++ b/src/bindings/bnd_pointcloud.cpp @@ -808,8 +808,12 @@ BND_DICT BND_PointCloud::ToThreejsJSON() const ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initPointCloudBindings(py::module_& m){} +#else namespace py = pybind11; -void initPointCloudBindings(pybind11::module& m) +void initPointCloudBindings(py::module& m) { py::class_(m, "PointCloudItem") .def_property("Location", &BND_PointCloudItem::GetLocation, &BND_PointCloudItem::SetLocation) @@ -870,6 +874,7 @@ void initPointCloudBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_pointgeometry.cpp b/src/bindings/bnd_pointgeometry.cpp index dcdccfae..c872e85d 100644 --- a/src/bindings/bnd_pointgeometry.cpp +++ b/src/bindings/bnd_pointgeometry.cpp @@ -25,8 +25,12 @@ void BND_Point::SetTrackedPointer(ON_Point* point, const ON_ModelComponentRefere ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initPointGeometryBindings(py::module_& m){} +#else namespace py = pybind11; -void initPointGeometryBindings(pybind11::module& m) +void initPointGeometryBindings(py::module& m) { py::class_(m, "Point") .def(py::init<>()) @@ -35,6 +39,7 @@ void initPointGeometryBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_pointgrid.cpp b/src/bindings/bnd_pointgrid.cpp index 01ebaece..3cecfc9c 100644 --- a/src/bindings/bnd_pointgrid.cpp +++ b/src/bindings/bnd_pointgrid.cpp @@ -19,14 +19,19 @@ void BND_PointGrid::SetTrackedPointer(ON_PointGrid* pointgrid, const ON_ModelCom ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initPointGridBindings(py::module_& m){} +#else namespace py = pybind11; -void initPointGridBindings(pybind11::module& m) +void initPointGridBindings(py::module& m) { py::class_(m, "PointGrid") .def(py::init<>()) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_polycurve.cpp b/src/bindings/bnd_polycurve.cpp index 76acecb7..ca5a7e74 100644 --- a/src/bindings/bnd_polycurve.cpp +++ b/src/bindings/bnd_polycurve.cpp @@ -110,8 +110,12 @@ int BND_PolyCurve::SegmentIndex(double polycurveParameter) const ///////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initPolyCurveBindings(py::module_& m){} +#else namespace py = pybind11; -void initPolyCurveBindings(pybind11::module& m) +void initPolyCurveBindings(py::module& m) { py::class_(m, "PolyCurve") .def(py::init<>()) @@ -132,6 +136,7 @@ void initPolyCurveBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_polyline.cpp b/src/bindings/bnd_polyline.cpp index f59136dd..a9c2a24a 100644 --- a/src/bindings/bnd_polyline.cpp +++ b/src/bindings/bnd_polyline.cpp @@ -192,8 +192,12 @@ void BND_Point3dList::Append2 (const std::vector& points) ////////////////////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initPolylineBindings(py::module_& m){} +#else namespace py = pybind11; -void initPolylineBindings(pybind11::module& m) +void initPolylineBindings(py::module& m) { py::class_(m, "Point3dList") .def(py::init<>()) @@ -242,6 +246,7 @@ void initPolylineBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_polylinecurve.cpp b/src/bindings/bnd_polylinecurve.cpp index b7b305aa..eff1d12f 100644 --- a/src/bindings/bnd_polylinecurve.cpp +++ b/src/bindings/bnd_polylinecurve.cpp @@ -62,8 +62,12 @@ BND_Polyline* BND_PolylineCurve::ToPolyline() const ////////////////////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initPolylineCurveBindings(py::module_& m){} +#else namespace py = pybind11; -void initPolylineCurveBindings(pybind11::module& m) +void initPolylineCurveBindings(py::module& m) { py::class_(m, "PolylineCurve") .def(py::init<>()) @@ -76,6 +80,7 @@ void initPolylineCurveBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_post_effects.cpp b/src/bindings/bnd_post_effects.cpp index c66394e7..3fbe8bd4 100644 --- a/src/bindings/bnd_post_effects.cpp +++ b/src/bindings/bnd_post_effects.cpp @@ -179,8 +179,12 @@ int BND_File3dmPostEffectTable::Count() const ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initPostEffectBindings(py::module_& m){} +#else namespace py = pybind11; -void initPostEffectBindings(pybind11::module& m) +void initPostEffectBindings(py::module& m) { py::class_(m, "PostEffect") .def(py::init<>()) @@ -197,6 +201,7 @@ void initPostEffectBindings(pybind11::module& m) } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_render_channels.cpp b/src/bindings/bnd_render_channels.cpp index 203f0c91..a4e3aaab 100644 --- a/src/bindings/bnd_render_channels.cpp +++ b/src/bindings/bnd_render_channels.cpp @@ -66,8 +66,12 @@ void BND_File3dmRenderChannels::SetCustomList(BND_TUPLE tuple) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initRenderChannelsBindings(py::module_& m){} +#else namespace py = pybind11; -void initRenderChannelsBindings(pybind11::module& m) +void initRenderChannelsBindings(py::module& m) { py::class_(m, "RenderChannels") .def(py::init<>()) @@ -77,6 +81,7 @@ void initRenderChannelsBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_render_content.cpp b/src/bindings/bnd_render_content.cpp index 56a0d7c2..91fbaaac 100644 --- a/src/bindings/bnd_render_content.cpp +++ b/src/bindings/bnd_render_content.cpp @@ -444,8 +444,12 @@ BND_File3dmRenderContent* BND_File3dmRenderContentTable::FindId(BND_UUID id) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initRenderContentBindings(py::module_& m){} +#else namespace py = pybind11; -void initRenderContentBindings(pybind11::module& m) +void initRenderContentBindings(py::module& m) { py::class_(m, "RenderContent") .def(py::init<>()) @@ -503,6 +507,7 @@ void initRenderContentBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_render_environments.cpp b/src/bindings/bnd_render_environments.cpp index 3e831f22..6af469d2 100644 --- a/src/bindings/bnd_render_environments.cpp +++ b/src/bindings/bnd_render_environments.cpp @@ -87,8 +87,12 @@ void BND_File3dmRenderEnvironments::SetReflectionId(const BND_UUID& id) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initRenderEnvironmentsBindings(py::module_& m){} +#else namespace py = pybind11; -void initRenderEnvironmentsBindings(pybind11::module& m) +void initRenderEnvironmentsBindings(py::module& m) { py::class_(m, "RenderEnvironments") .def(py::init<>()) @@ -101,6 +105,7 @@ void initRenderEnvironmentsBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_revsurface.cpp b/src/bindings/bnd_revsurface.cpp index 706176c5..b3a00e5e 100644 --- a/src/bindings/bnd_revsurface.cpp +++ b/src/bindings/bnd_revsurface.cpp @@ -37,8 +37,12 @@ BND_RevSurface* BND_RevSurface::Create1(const BND_Curve& revoluteCurve, const ON ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initRevSurfaceBindings(py::module_& m){} +#else namespace py = pybind11; -void initRevSurfaceBindings(pybind11::module& m) +void initRevSurfaceBindings(py::module& m) { py::class_(m, "RevSurface") .def(py::init<>()) @@ -46,6 +50,7 @@ void initRevSurfaceBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_rtree.cpp b/src/bindings/bnd_rtree.cpp index dbfeab82..3d17f64b 100644 --- a/src/bindings/bnd_rtree.cpp +++ b/src/bindings/bnd_rtree.cpp @@ -3,14 +3,19 @@ #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initRTreeBindings(py::module_& m){} +#else namespace py = pybind11; -void initRTreeBindings(pybind11::module& m) +void initRTreeBindings(py::module& m) { //py::class_(m, "RTree") // .def(py::init<>()) // ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_safe_frame.cpp b/src/bindings/bnd_safe_frame.cpp index 749d77db..9a092569 100644 --- a/src/bindings/bnd_safe_frame.cpp +++ b/src/bindings/bnd_safe_frame.cpp @@ -32,8 +32,12 @@ BND_File3dmSafeFrame::BND_File3dmSafeFrame(ON_SafeFrame* sf) } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initSafeFrameBindings(py::module_& m){} +#else namespace py = pybind11; -void initSafeFrameBindings(pybind11::module& m) +void initSafeFrameBindings(py::module& m) { py::class_(m, "SafeFrame") .def(py::init<>()) @@ -53,6 +57,7 @@ void initSafeFrameBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_skylight.cpp b/src/bindings/bnd_skylight.cpp index 4eb5fdfc..d47a9920 100644 --- a/src/bindings/bnd_skylight.cpp +++ b/src/bindings/bnd_skylight.cpp @@ -32,8 +32,12 @@ BND_File3dmSkylight::BND_File3dmSkylight(ON_Skylight* sl) } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initSkylightBindings(py::module_& m){} +#else namespace py = pybind11; -void initSkylightBindings(pybind11::module& m) +void initSkylightBindings(py::module& m) { py::class_(m, "Skylight") .def(py::init<>()) @@ -43,6 +47,7 @@ void initSkylightBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_sphere.cpp b/src/bindings/bnd_sphere.cpp index 485edfdf..517d9375 100644 --- a/src/bindings/bnd_sphere.cpp +++ b/src/bindings/bnd_sphere.cpp @@ -117,8 +117,12 @@ BND_Sphere* BND_Sphere::Decode(emscripten::val jsonObject) #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initSphereBindings(py::module_& m){} +#else namespace py = pybind11; -void initSphereBindings(pybind11::module& m) +void initSphereBindings(py::module& m) { py::class_(m, "Sphere") .def(py::init(), py::arg("center"), py::arg("radius")) @@ -143,6 +147,7 @@ void initSphereBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_subd.cpp b/src/bindings/bnd_subd.cpp index 11eb9bae..1d9569ab 100644 --- a/src/bindings/bnd_subd.cpp +++ b/src/bindings/bnd_subd.cpp @@ -18,8 +18,12 @@ BND_SubD::BND_SubD() #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initSubDBindings(py::module_& m){} +#else namespace py = pybind11; -void initSubDBindings(pybind11::module& m) +void initSubDBindings(py::module& m) { py::class_(m, "SubD") .def(py::init<>()) @@ -30,6 +34,7 @@ void initSubDBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_sun.cpp b/src/bindings/bnd_sun.cpp index 8794bd45..c072abbd 100644 --- a/src/bindings/bnd_sun.cpp +++ b/src/bindings/bnd_sun.cpp @@ -108,8 +108,12 @@ BND_Color BND_File3dmSun::GetSunColorFromAltitude(double v) // Static. ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initSunBindings(py::module_& m){} +#else namespace py = pybind11; -void initSunBindings(pybind11::module& m) +void initSunBindings(py::module& m) { py::class_(m, "Sun") .def(py::init<>()) @@ -140,6 +144,7 @@ void initSunBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_surface.cpp b/src/bindings/bnd_surface.cpp index d2fdc718..118d0982 100644 --- a/src/bindings/bnd_surface.cpp +++ b/src/bindings/bnd_surface.cpp @@ -124,8 +124,12 @@ BND_TUPLE BND_Surface::GetNurbsFormParameterFromSurfaceParameter(double surfaceS #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initSurfaceBindings(py::module_& m){} +#else namespace py = pybind11; -void initSurfaceBindings(pybind11::module& m) +void initSurfaceBindings(py::module& m) { py::class_(m, "Surface") .def_property_readonly("IsSolid", &BND_Surface::IsSolid) @@ -155,6 +159,7 @@ void initSurfaceBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_surfaceproxy.cpp b/src/bindings/bnd_surfaceproxy.cpp index 00eed892..eae6a00e 100644 --- a/src/bindings/bnd_surfaceproxy.cpp +++ b/src/bindings/bnd_surfaceproxy.cpp @@ -17,13 +17,18 @@ BND_SurfaceProxy::BND_SurfaceProxy() #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initSurfaceProxyBindings(py::module_& m){} +#else namespace py = pybind11; -void initSurfaceProxyBindings(pybind11::module& m) +void initSurfaceProxyBindings(py::module& m) { py::class_(m, "SurfaceProxy") ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_texture.cpp b/src/bindings/bnd_texture.cpp index a3559ae5..102a2189 100644 --- a/src/bindings/bnd_texture.cpp +++ b/src/bindings/bnd_texture.cpp @@ -78,8 +78,12 @@ void BND_Environment::SetTrackedPointer(ON_Environment* env, const ON_ModelCompo ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initEnvironmentBindings(py::module_& m){} +#else namespace py = pybind11; -void initEnvironmentBindings(pybind11::module& m) +void initEnvironmentBindings(py::module& m) { py::class_(m, "Environment") .def(py::init<>()) @@ -89,6 +93,7 @@ void initEnvironmentBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_texture_mapping.cpp b/src/bindings/bnd_texture_mapping.cpp index 78f7828e..8edb8235 100644 --- a/src/bindings/bnd_texture_mapping.cpp +++ b/src/bindings/bnd_texture_mapping.cpp @@ -138,8 +138,12 @@ std::tuple BND_TextureMapping::Evaluate(const ON_3dPoint& P, co #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initTextureMappingBindings(py::module_& m){} +#else namespace py = pybind11; -void initTextureMappingBindings(pybind11::module& m) +void initTextureMappingBindings(py::module& m) { py::class_(m, "TextureMapping") .def(py::init<>()) @@ -163,6 +167,7 @@ void initTextureMappingBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_uuid.cpp b/src/bindings/bnd_uuid.cpp index af2feeaa..c6e24fc3 100644 --- a/src/bindings/bnd_uuid.cpp +++ b/src/bindings/bnd_uuid.cpp @@ -1,6 +1,10 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +#else +namespace py = pybind11; static pybind11::object make_uuid; BND_UUID ON_UUID_to_Binding(const ON_UUID& id) @@ -35,6 +39,7 @@ std::vector ON_SimpleArrayUUID_to_Binding(const ON_SimpleArray(m, "ViewportInfo") .def(py::init<>()) @@ -408,9 +416,10 @@ void initViewportBindings(pybind11::module& m) .def_property_readonly("Id", &BND_Viewport::GetId) ; } +#endif +#endif -#else - +#if defined(ON_WASM_COMPILE) using namespace emscripten; void initViewportBindings(void*) diff --git a/src/bindings/bnd_xform.cpp b/src/bindings/bnd_xform.cpp index d4377132..a0de7e72 100644 --- a/src/bindings/bnd_xform.cpp +++ b/src/bindings/bnd_xform.cpp @@ -115,8 +115,12 @@ BND_TUPLE BND_Transform::ToFloatArray(bool rowDominant) const } #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) +namespace py = nanobind; +void initXformBindings(py::module_& m){} +#else namespace py = pybind11; -void initXformBindings(pybind11::module& m) +void initXformBindings(py::module& m) { py::class_(m, "Transform") .def(py::init(), py::arg("diagonalValue")) @@ -181,6 +185,7 @@ void initXformBindings(pybind11::module& m) ; } #endif +#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt new file mode 100644 index 00000000..4e95bfee --- /dev/null +++ b/tests/cpp/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.16) +project(ON_Test) + +# GoogleTest requires at least C++14 +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/b10fad38c4026a29ea6561ab15fc4818170d1c10.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +add_subdirectory(../../src/lib/opennurbs build_opennurbs) +if (MSVC) + add_definitions(-DOPENNURBS_IMPORTS) +endif() + +#[[ +# run UpdateVersionNumbers before compiling C++ projects +add_custom_target(updateversionnumbers ALL + COMMAND sh -c "dotnet build ../../../UpdateVersionNumbers.csproj" + BYPRODUCTS version.h + COMMENT "Create version source files" + ) +]] + +# Add tests +function(set_test TESTNAME) + add_executable(${TESTNAME} ${ARGN}) + #add_dependencies(${TESTNAME} updateversionnumbers) + target_link_libraries(${TESTNAME} GTest::gtest_main OpenNURBS) + # we occasionally get an error building on Windows. Adding discovery mode + # pre-test fixes this, though I'm not sure what the drawbacks are + gtest_discover_tests(${TESTNAME} DISCOVERY_MODE PRE_TEST) +endfunction() + +include(GoogleTest) + +# devs: to add a test use set_test(testName testName.cpp) +set_test(test_ON_View ontest_view.cpp) \ No newline at end of file diff --git a/tests/cpp/ontest_view.cpp b/tests/cpp/ontest_view.cpp new file mode 100644 index 00000000..4466f098 --- /dev/null +++ b/tests/cpp/ontest_view.cpp @@ -0,0 +1,76 @@ +#include +#include "../../src/lib/opennurbs/opennurbs_public.h" +#include +#include +#include + +namespace fs = std::filesystem; + +TEST(ONTest, ONTestViewPort) +{ + + ON::Begin(); + + // errors printed to stdout + ON_TextLog error_log; + + //create model + ONX_Model model; + + // create viewport + ON_3dmView view; + + view.m_name = L"Test View"; + ON_3dPoint loc(50, 50, 50); + view.m_vp.SetCameraLocation(loc); + + model.m_settings.m_views.Append(view); + + ON_Sphere sphere1(ON_3dPoint(0, 0, 0), 10); + ON_NurbsSurface s1; + sphere1.GetNurbForm(s1); + model.AddModelGeometryComponent(&s1, nullptr); + ON_Sphere sphere2(ON_3dPoint(50, 50, 0), 10); + ON_NurbsSurface s2; + sphere2.GetNurbForm(s2); + model.AddModelGeometryComponent(&s2, nullptr); + ON_Sphere sphere3(ON_3dPoint(100, 100, 100), 10); + ON_NurbsSurface s3; + sphere3.GetNurbForm(s3); + model.AddModelGeometryComponent(&s3, nullptr); + + fs::path dir = fs::current_path(); + + if (dir.filename().string() == "build") + { + dir = dir.parent_path(); + } + + //save file + int version = 0; + const wchar_t* filename = L"file3dmWithViews_cpp.3dm"; + + std::wstring full_path = dir.wstring() + L"\\" + filename; + + // writes model to archive + model.Write( full_path.c_str(), version, &error_log ); + + FILE *fp = ON_FileStream::Open3dmToRead(full_path.c_str()); + + ON_BinaryFile archive(ON::archive_mode::read3dm, fp); + + ONX_Model model_read; + ON_TextLog log; + bool rc = model_read.Read(archive, &log); + + ON_3dPoint loc_read(model_read.m_settings.m_views[0].m_vp.CameraLocation() ); + + std::cout << "loc " + std::to_string(loc.x) + "," + std::to_string(loc.y) + "," + std::to_string(loc.z) << std::endl; + std::cout << "loc_read " + std::to_string(loc_read.x) + "," + std::to_string(loc_read.y) + "," + std::to_string(loc_read.z) << std::endl; + + EXPECT_EQ(loc.x, loc_read.x); + EXPECT_EQ(loc.y, loc_read.y); + EXPECT_EQ(loc.z, loc_read.z); + + ON::End(); +} \ No newline at end of file diff --git a/tests/dotnet/file3dm.ViewTable.cs b/tests/dotnet/file3dm.ViewTable.cs new file mode 100644 index 00000000..8fd324b7 --- /dev/null +++ b/tests/dotnet/file3dm.ViewTable.cs @@ -0,0 +1,72 @@ +namespace rhino3dm_test; + +using Rhino.FileIO; +using Rhino.Geometry; +using System.IO; + +public class File3dm_ViewTable_Tests +{ + [SetUp] + public void Setup() + { + } + + [Test] + public void ViewTable_CreateFileWithVuew() + { + File3dm file3dm = new File3dm(); + file3dm.ApplicationName = "rhino3dm.net"; + file3dm.ApplicationUrl = "https://www.rhino3d.com"; + file3dm.ApplicationDetails = "ViewTable Tests: CreateFileWithView"; + + var rand = new System.Random(); + + // make some geometry + for( int i = 0; i < 100; i ++) + { + + var x = rand.NextDouble() * 100; + var y = rand.NextDouble() * 100; + var z = rand.NextDouble() * 100; + var position = new Point3d(x,y,z); + var sphere = new Sphere(position, 10); + + file3dm.Objects.AddSphere(sphere); + + } + + var vi = new Rhino.DocObjects.ViewInfo(); + vi.Name = "Main"; + + var loc = new Point3d(50, 50, 50); + var res = vi.Viewport.SetCameraLocation(loc); + var loc2 = vi.Viewport.CameraLocation; + + Console.WriteLine("Number of views: {0}", file3dm.Views.Count); + file3dm.Views.Add(vi); + Console.WriteLine("Number of views: {0}", file3dm.Views.Count); + + var vi_2 = file3dm.AllViews[0]; + Console.WriteLine("Name of view: {0}", vi_2.Name); + var loc3 = vi_2.Viewport.CameraLocation; + + var path = Path.GetTempPath(); + var filePath = Path.Join(path, "fileWithView.3dm"); + + file3dm.Write(filePath, 8); + + var file3dm_read = File3dm.Read(filePath); + var vi_read = file3dm_read.AllViews[0]; + + var loc_read = vi_read.Viewport.CameraLocation; + + Console.WriteLine("Camera location orig: {0}, {1}, {2}",loc.X, loc.Y, loc.Z); + Console.WriteLine("Camera location after: {0}, {1}, {2}",loc2.X, loc2.Y, loc2.Z); + Console.WriteLine("Camera location file3dm: {0}, {1}, {2}",loc3.X, loc3.Y, loc3.Z); + Console.WriteLine("Camera location read: {0}, {1}, {2}",loc_read.X, loc_read.Y, loc_read.Z); + + Assert.IsTrue( loc.X == loc2.X && loc.Y == loc2.Y && loc.Z == loc2.Z ); + Assert.IsTrue( loc.X == loc3.X && loc.Y == loc3.Y && loc.Z == loc3.Z ); + Assert.IsTrue( loc.X == loc_read.X && loc.Y == loc_read.Y && loc.Z == loc_read.Z ); + } +} \ No newline at end of file diff --git a/tests/javascript/file3dm.ViewTable.test.js b/tests/javascript/file3dm.ViewTable.test.js new file mode 100644 index 00000000..c2e75c9d --- /dev/null +++ b/tests/javascript/file3dm.ViewTable.test.js @@ -0,0 +1,57 @@ +const rhino3dm = require('rhino3dm') +const fs = require('fs') + +let rhino +beforeEach(async () => { + rhino = await rhino3dm() +}) +//TODO +test('CreateFileWithView', async () => { + + const file3dm = new rhino.File3dm() + file3dm.applicationName = 'rhino3dm.js' + file3dm.applicationDetails = 'rhino3dm-tests' + file3dm.applicationUrl = 'https://rhino3d.com' + + // make some geometry + for (let i = 0; i < 100; i++) { + + const x = Math.random() * 100 + const y = Math.random() * 100 + const z = Math.random() * 100 + const sphere = new rhino.Sphere([x, y, z], 10) + + file3dm.objects().addSphere(sphere, null) + + } + + const vi = new rhino.ViewInfo() + vi.name = 'main_js' + + //does not work + /* + vi.getViewport().setCameraLocation([50, 50, 100]) + loc = vi.getViewport().cameraLocation //<-- default location + */ + + // works + const vp = new rhino.ViewportInfo() + const loc = [50,50,100] + vp.setCameraLocation(loc) + vi.setViewport(vp) + file3dm.views().add(vi) + + const bufferWrite = file3dm.toByteArray() + fs.writeFileSync('test_createFileWithView.3dm', bufferWrite) + + const bufferRead = fs.readFileSync('test_createFileWithView.3dm') + const arr = new Uint8Array(bufferRead) + const file3dmRead = rhino.File3dm.fromByteArray(arr) + + const vi_read = file3dmRead.views().get(0) + const vp_read = vi_read.getViewport() + const loc_read = vp_read.cameraLocation + + expect(loc[0] === loc_read[0] && loc[1] === loc_read[1] && loc[2] === loc_read[2]).toBe(true) + +}) \ No newline at end of file diff --git a/tests/python/test_File3dm_ViewTable.py b/tests/python/test_File3dm_ViewTable.py new file mode 100644 index 00000000..4be47552 --- /dev/null +++ b/tests/python/test_File3dm_ViewTable.py @@ -0,0 +1,47 @@ +import rhino3dm +import unittest + +#objective: to test creating file with layers and reasing a file with layers +class TestFile3dmViewTable(unittest.TestCase): + def test_createFileWithView(self): + + import random + + file3dm = rhino3dm.File3dm() + file3dm.ApplicationName = 'rhino3dm.py' + file3dm.ApplicationDetails = 'rhino3dm-tests' + file3dm.ApplicationUrl = 'https://rhino3d.com' + + for i in range(100): + x = random.random() * 100 + y = random.random() * 100 + z = random.random() * 100 + sphere = rhino3dm.Sphere(rhino3dm.Point3d(x, y, z), 10) + file3dm.Objects.AddSphere(sphere, None) + + vp = rhino3dm.ViewportInfo() + loc = rhino3dm.Point3d(50, 50, 50) + vp.SetCameraLocation(loc) + view = rhino3dm.ViewInfo() + view.Name = "Main_py" + view.Viewport = vp + loc2 = view.Viewport.CameraLocation + + file3dm.Views.Add(view) + + file3dm.Write("CreateFileWithView_py.3dm", 8) + + file3dm_read = rhino3dm.File3dm.Read("CreateFileWithView_py.3dm") + vi_read = file3dm_read.Views[0] + loc_read = vi_read.Viewport.CameraLocation + + print(loc.X, loc.Y, loc.Z) + print(loc2.X, loc2.Y, loc2.Z) + print(loc_read.X, loc_read.Y, loc_read.Z) + + self.assertTrue(loc.X == loc_read.X and loc.Y == loc_read.Y and loc.Z == loc_read.Z) + +if __name__ == '__main__': + print("running tests") + unittest.main() + print("tests complete") \ No newline at end of file From 49413d02df0df753c90146824b52248a354679cf Mon Sep 17 00:00:00 2001 From: fraguada Date: Mon, 5 Aug 2024 18:33:24 +0200 Subject: [PATCH 05/27] update bindings.h/.cpp --- src/CMakeLists.txt | 3 ++- src/bindings/bindings.cpp | 2 +- src/bindings/bindings.h | 24 ++++++++++-------------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 05614fa0..ebc77795 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,13 +17,14 @@ if (${RHINO3DM_PY}) message("Python Compile") if(PYTHON_BINDING_LIB STREQUAL "NANOBIND") message("Using nanobind") + add_compile_definitions( NANOBIND ) if (CMAKE_VERSION VERSION_LESS 3.18) set(DEV_MODULE Development) else() set(DEV_MODULE Development.Module) endif() find_package(Python COMPONENTS Interpreter ${DEV_MODULE} REQUIRED) - add_compile_definitions( NANOBIND ) + add_subdirectory(lib/nanobind) else() message("Using pybind11") diff --git a/src/bindings/bindings.cpp b/src/bindings/bindings.cpp index c8b3aa88..634584e8 100644 --- a/src/bindings/bindings.cpp +++ b/src/bindings/bindings.cpp @@ -98,7 +98,7 @@ EMSCRIPTEN_BINDINGS(rhino3dm) { BND_TUPLE CreateTuple(int count) { #if defined(ON_PYTHON_COMPILE) - py::tuple rc(count); + BND_TUPLE rc = py::make_tuple(count); #else emscripten::val rc(emscripten::val::array()); #endif diff --git a/src/bindings/bindings.h b/src/bindings/bindings.h index 7da9b5ea..2a156171 100644 --- a/src/bindings/bindings.h +++ b/src/bindings/bindings.h @@ -7,26 +7,22 @@ #define ON_WASM_COMPILE #else #define ON_PYTHON_COMPILE +#if defined(NANOBIND) + #include + #include + #include + namespace py = nanobind; +#else + #include + #include + namespace py = pybind11; #endif - -#include "../lib/opennurbs/opennurbs.h" - -#if defined(ON_PYTHON_COMPILE) - #if defined(NANOBIND) - namespace py = nanobind; - #include - #include - #include - #else - namespace py = pybind11; - #include - #include - #endif #include "datetime.h" #pragma comment(lib, "rpcrt4.lib") #pragma comment(lib, "shlwapi.lib") #endif +#include "../lib/opennurbs/opennurbs.h" #if defined(ON_WASM_COMPILE) #include From 96c5d611bde51acc5d03c3a4f58c7b162e259e4b Mon Sep 17 00:00:00 2001 From: Steve Baer Date: Mon, 5 Aug 2024 14:57:21 -0700 Subject: [PATCH 06/27] closer to a compile --- src/bindings/bindings.cpp | 23 +++++--- src/bindings/bindings.h | 14 +++++ src/bindings/bnd_extensions.cpp | 27 +++++---- src/bindings/bnd_file_utilities.cpp | 8 +-- src/bindings/bnd_intersect.cpp | 3 +- src/bindings/bnd_mesh.cpp | 43 ++++++++++---- src/bindings/bnd_nurbscurve.cpp | 8 +-- src/bindings/bnd_nurbssurface.cpp | 10 ++-- src/bindings/bnd_object.cpp | 89 +++++++++++++++-------------- src/bindings/bnd_plane.cpp | 20 +++++-- src/bindings/bnd_pointcloud.cpp | 2 +- src/bindings/bnd_polyline.cpp | 2 +- src/bindings/bnd_render_content.cpp | 4 +- src/bindings/bnd_sphere.cpp | 12 ++-- src/bindings/bnd_texture.cpp | 3 +- src/bindings/bnd_viewport.cpp | 8 +-- src/create_python_vcxproj.py | 2 +- 17 files changed, 160 insertions(+), 118 deletions(-) diff --git a/src/bindings/bindings.cpp b/src/bindings/bindings.cpp index 634584e8..7d02a747 100644 --- a/src/bindings/bindings.cpp +++ b/src/bindings/bindings.cpp @@ -1,16 +1,9 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -NB_MODULE(_rhino3dm, m) { - m.doc() = "rhino3dm python package. OpenNURBS wrappers with a RhinoCommon style"; -#else -namespace py = pybind11; -PYBIND11_MODULE(_rhino3dm, m){ +RH3DM_PYTHON_BINDING(_rhino3dm, m) { m.doc() = "rhino3dm python package. OpenNURBS wrappers with a RhinoCommon style"; #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; @@ -95,6 +88,14 @@ EMSCRIPTEN_BINDINGS(rhino3dm) { } +#if defined(ON_PYTHON_COMPILE) +std::string ToStdString(const py::str& str) +{ + std::string rc = str; + return rc; +} +#endif + BND_TUPLE CreateTuple(int count) { #if defined(ON_PYTHON_COMPILE) @@ -108,7 +109,11 @@ BND_TUPLE CreateTuple(int count) BND_TUPLE NullTuple() { #if defined(ON_PYTHON_COMPILE) - return py::none(); +#if defined(NANOBIND) + UNIMPLEMENTED_EXCEPTION; +#else + return py::none(); +#endif #else return emscripten::val::null(); #endif diff --git a/src/bindings/bindings.h b/src/bindings/bindings.h index 2a156171..59df0167 100644 --- a/src/bindings/bindings.h +++ b/src/bindings/bindings.h @@ -12,11 +12,21 @@ #include #include namespace py = nanobind; + typedef nanobind::module_ rh3dmpymodule; +#define RH3DM_PYTHON_BINDING(name, variable) NB_MODULE(name, variable) +#define def_property def_prop_rw +#define def_property_readonly def_prop_ro +#define UNIMPLEMENTED_EXCEPTION throw std::exception() + #else #include #include namespace py = pybind11; + #define RH3DM_PYTHON_BINDING(name, variable) PYBIND11_MODULE(name, variable) + typedef pybind11::module_ rh3dmpymodule; #endif + +std::string ToStdString(const py::str& str); #include "datetime.h" #pragma comment(lib, "rpcrt4.lib") #pragma comment(lib, "shlwapi.lib") @@ -50,7 +60,11 @@ template void SetTuple(BND_TUPLE& tuple, int index, const T& value) { #if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) + UNIMPLEMENTED_EXCEPTION; +#else tuple[index] = value; +#endif #else tuple.set(index, value); #endif diff --git a/src/bindings/bnd_extensions.cpp b/src/bindings/bnd_extensions.cpp index 39858572..3f5b09a5 100644 --- a/src/bindings/bnd_extensions.cpp +++ b/src/bindings/bnd_extensions.cpp @@ -671,7 +671,7 @@ BND_FileObject* BND_ONXModel_ObjectTable::ModelObjectAt(int index) { #if defined(ON_PYTHON_COMPILE) if (index < 0) - throw pybind11::index_error(); + throw py::index_error(); #else if (index < 0) return nullptr; @@ -706,7 +706,7 @@ BND_FileObject* BND_ONXModel_ObjectTable::ModelObjectAt(int index) } #if defined(ON_PYTHON_COMPILE) - throw pybind11::index_error(); + throw py::index_error(); #else return nullptr; #endif @@ -775,7 +775,7 @@ BND_Material* BND_File3dmMaterialTable::FindIndex(int index) return new BND_Material(modelmaterial, &compref); #if defined(ON_PYTHON_COMPILE) - throw pybind11::index_error(); + throw py::index_error(); #else return nullptr; #endif @@ -930,7 +930,7 @@ BND_Bitmap* BND_File3dmBitmapTable::FindIndex(int index) return new BND_Bitmap(modelbitmap, &compref); #if defined(ON_PYTHON_COMPILE) - throw pybind11::index_error(); + throw py::index_error(); #else return nullptr; #endif @@ -994,7 +994,7 @@ BND_Layer* BND_File3dmLayerTable::FindIndex(int index) return new BND_Layer(modellayer, &compref, m_model); #if defined(ON_PYTHON_COMPILE) - throw pybind11::index_error(); + throw py::index_error(); #else return nullptr; #endif @@ -1056,7 +1056,7 @@ BND_Group* BND_File3dmGroupTable::FindIndex(int index) } #if defined(ON_PYTHON_COMPILE) - throw pybind11::index_error(); + throw py::index_error(); #else return nullptr; #endif @@ -1129,7 +1129,7 @@ BND_ViewInfo* BND_File3dmViewTable::GetItem(int index) const #if defined(ON_PYTHON_COMPILE) if (index < 0 || index >= count) - throw pybind11::index_error(); + throw py::index_error(); #else if (index < 0 || index >= count) return nullptr; @@ -1176,7 +1176,7 @@ BND_DimensionStyle* BND_File3dmDimStyleTable::FindIndex(int index) const return new BND_DimensionStyle(modeldimstyle, &compref); #if defined(ON_PYTHON_COMPILE) - throw pybind11::index_error(); + throw py::index_error(); #else return nullptr; #endif @@ -1234,8 +1234,8 @@ int BND_File3dmInstanceDefinitionTable::Add(std::wstring name, std::wstring desc { #if defined(ON_PYTHON_COMPILE) - BND_GeometryBase g = geometry[i].cast(); - BND_3dmObjectAttributes oa = attributes[i].cast(); + BND_GeometryBase g = py::cast(geometry[i]); + BND_3dmObjectAttributes oa = py::cast(attributes[i]); #else BND_GeometryBase g = geometry[i].as(); BND_3dmObjectAttributes oa = attributes[i].as(); @@ -1318,7 +1318,7 @@ BND_InstanceDefinitionGeometry* BND_File3dmInstanceDefinitionTable::FindIndex(in } #if defined(ON_PYTHON_COMPILE) - throw pybind11::index_error(); + throw py::index_error(); #else return nullptr; #endif @@ -1363,7 +1363,7 @@ BND_File3dmPlugInData* BND_File3dmPlugInDataTable::GetPlugInData(int index) { #if defined(ON_PYTHON_COMPILE) if (index < 0 || index >= m_model->m_userdata_table.Count()) - throw pybind11::index_error(); + throw py::index_error(); #else if (index < 0 || index >= m_model->m_userdata_table.Count()) return nullptr; @@ -1415,7 +1415,7 @@ BND_TUPLE BND_File3dmStringTable::GetKeyValue(int i) const #if defined(ON_PYTHON_COMPILE) if (i < 0 || i >= strings.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif const ON_UserString& us = strings[i]; @@ -1626,7 +1626,6 @@ BND_TUPLE BND_FileObject::GetTextureMapping( const class BND_File3dm* file3dm, i // --------------------- Iterator helpers ------- // #if defined(ON_PYTHON_COMPILE) -namespace py = pybind11; template struct PyBNDIterator { diff --git a/src/bindings/bnd_file_utilities.cpp b/src/bindings/bnd_file_utilities.cpp index 61b11de2..1ecba909 100644 --- a/src/bindings/bnd_file_utilities.cpp +++ b/src/bindings/bnd_file_utilities.cpp @@ -20,12 +20,7 @@ BND_FileReference BND_FileReference::CreateFromFullAndRelativePaths(std::wstring ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initFileUtilitiesBindings(py::module_& m){} -#else -namespace py = pybind11; -void initFileUtilitiesBindings(py::module& m) +void initFileUtilitiesBindings(rh3dmpymodule& m) { py::class_(m, "FileReference") .def_static("CreateFromFullPath", &BND_FileReference::CreateFromFullPath, py::arg("path")) @@ -35,7 +30,6 @@ void initFileUtilitiesBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_intersect.cpp b/src/bindings/bnd_intersect.cpp index 8f09f91d..b9628665 100644 --- a/src/bindings/bnd_intersect.cpp +++ b/src/bindings/bnd_intersect.cpp @@ -210,8 +210,7 @@ BND_TUPLE BND_Intersection::LineBox(const ON_Line& line, const BND_BoundingBox& ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -namespace py = pybind11; -void initIntersectBindings(pybind11::module& m) +void initIntersectBindings(py::module_& m) { //py::enum_(m, "PlaneCircleIntersection") // .value("None", PlaneCircleIntersection::None) diff --git a/src/bindings/bnd_mesh.cpp b/src/bindings/bnd_mesh.cpp index f14f15bf..78711ed4 100644 --- a/src/bindings/bnd_mesh.cpp +++ b/src/bindings/bnd_mesh.cpp @@ -4,9 +4,9 @@ #if defined(ON_PYTHON_COMPILE) -pybind11::dict BND_MeshingParameters::Encode() const +py::dict BND_MeshingParameters::Encode() const { - pybind11::dict d; + py::dict d; d["TextureRange"] = GetTextureRange(); d["JaggedSeams"] = GetJaggedSeams(); d["RefineGrid"] = GetRefineGrid(); @@ -27,9 +27,10 @@ pybind11::dict BND_MeshingParameters::Encode() const return d; } -BND_MeshingParameters* BND_MeshingParameters::Decode(pybind11::dict jsonObject) +BND_MeshingParameters* BND_MeshingParameters::Decode(py::dict jsonObject) { BND_MeshingParameters* mp = new BND_MeshingParameters(); + /* mp->SetTextureRange(jsonObject["TextureRange"].cast()); mp->SetJaggedSeams(jsonObject["JaggedSeams"].cast()); mp->SetRefineGrid(jsonObject["RefineGrid"].cast()); @@ -47,6 +48,24 @@ BND_MeshingParameters* BND_MeshingParameters::Decode(pybind11::dict jsonObject) mp->SetMinimumEdgeLength(jsonObject["MinimumEdgeLength"].cast()); mp->SetMaximumEdgeLength(jsonObject["MaximumEdgeLength"].cast()); mp->SetRefineAngle(jsonObject["RefineAngle"].cast()); + */ + mp->SetTextureRange(py::cast(jsonObject["TextureRange"])); + mp->SetJaggedSeams(py::cast(jsonObject["JaggedSeams"])); + mp->SetRefineGrid(py::cast(jsonObject["RefineGrid"])); + mp->SetSimplePlanes(py::cast(jsonObject["SimplePlanes"])); + mp->SetComputeCurvature(py::cast(jsonObject["ComputeCurvature"])); + mp->SetClosedObjectPostProcess(py::cast(jsonObject["ClosedObjectPostProcess"])); + mp->SetGridMinCount(py::cast(jsonObject["GridMinCount"])); + mp->SetGridMaxCount(py::cast(jsonObject["GridMaxCount"])); + mp->SetGridAngle(py::cast(jsonObject["GridAngle"])); + mp->SetGridAspectRatio(py::cast(jsonObject["GridAspectRatio"])); + mp->SetGridAmplification(py::cast(jsonObject["GridAmplification"])); + mp->SetTolerance(py::cast(jsonObject["Tolerance"])); + mp->SetMinimumTolerance(py::cast(jsonObject["MinimumTolerance"])); + mp->SetRelativeTolerance(py::cast(jsonObject["RelativeTolerance"])); + mp->SetMinimumEdgeLength(py::cast(jsonObject["MinimumEdgeLength"])); + mp->SetMaximumEdgeLength(py::cast(jsonObject["MaximumEdgeLength"])); + mp->SetRefineAngle(py::cast(jsonObject["RefineAngle"])); return mp; } #endif @@ -473,7 +492,7 @@ ON_3fPoint BND_MeshVertexList::GetVertex(int i) const { #if defined(ON_PYTHON_COMPILE) if (i<0 || i>=m_mesh->m_V.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif return m_mesh->m_V[i]; } @@ -482,7 +501,7 @@ void BND_MeshVertexList::SetVertex(int i, ON_3fPoint pt) { #if defined(ON_PYTHON_COMPILE) if (i < 0 || i >= m_mesh->m_V.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif m_mesh->m_V[i] = pt; } @@ -707,7 +726,7 @@ BND_TUPLE BND_MeshFaceList::GetFace(int i) const { #if defined(ON_PYTHON_COMPILE) if (i < 0 || i >= m_mesh->m_F.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif ON_MeshFace& face = m_mesh->m_F[i]; @@ -784,7 +803,7 @@ BND_Color BND_MeshVertexColorList::GetColor(int index) const { #if defined(ON_PYTHON_COMPILE) if (index < 0 || index >= m_mesh->m_C.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif return ON_Color_to_Binding(m_mesh->m_C[index]); } @@ -793,7 +812,7 @@ void BND_MeshVertexColorList::SetColor(int index, BND_Color color) { #if defined(ON_PYTHON_COMPILE) if (index < 0 || index >= m_mesh->m_C.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif // if index == count, then we are appending @@ -816,7 +835,7 @@ ON_3fVector BND_MeshNormalList::GetNormal(int i) const { #if defined(ON_PYTHON_COMPILE) if (i < 0 || i >= m_mesh->m_N.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif return m_mesh->m_N[i]; @@ -826,7 +845,7 @@ void BND_MeshNormalList::SetNormal(int i, ON_3fVector v) { #if defined(ON_PYTHON_COMPILE) if (i < 0 || i >= m_mesh->m_N.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif m_mesh->m_N[i] = v; } @@ -841,7 +860,7 @@ ON_2fPoint BND_MeshTextureCoordinateList::GetTextureCoordinate(int i) const { #if defined(ON_PYTHON_COMPILE) if (i<0 || i >= m_mesh->m_T.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif return m_mesh->m_T[i]; } @@ -850,7 +869,7 @@ void BND_MeshTextureCoordinateList::SetTextureCoordinate(int i, ON_2fPoint tc) { #if defined(ON_PYTHON_COMPILE) if (i < 0 || i >= m_mesh->m_T.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif m_mesh->m_T[i] = tc; } diff --git a/src/bindings/bnd_nurbscurve.cpp b/src/bindings/bnd_nurbscurve.cpp index 58cd4814..d6370811 100644 --- a/src/bindings/bnd_nurbscurve.cpp +++ b/src/bindings/bnd_nurbscurve.cpp @@ -11,7 +11,7 @@ ON_4dPoint BND_NurbsCurvePointList::GetControlPoint(int index) const { #if defined(ON_PYTHON_COMPILE) if (index >= Count() || index < 0) - throw pybind11::index_error("list index out of range"); + throw py::index_error("list index out of range"); #endif ON_4dPoint pt; m_nurbs_curve->GetCV(index, pt); @@ -22,7 +22,7 @@ void BND_NurbsCurvePointList::SetControlPoint(int index, ON_4dPoint point) { #if defined(ON_PYTHON_COMPILE) if (index >= Count() || index < 0) - throw pybind11::index_error("list index out of range"); + throw py::index_error("list index out of range"); #endif m_nurbs_curve->SetCV(index, point); } @@ -40,7 +40,7 @@ double BND_NurbsCurveKnotList::GetKnot(int index) const { #if defined(ON_PYTHON_COMPILE) if (index >= Count() || index < 0) - throw pybind11::index_error("list index out of range"); + throw py::index_error("list index out of range"); #endif return m_nurbs_curve->Knot(index); } @@ -49,7 +49,7 @@ void BND_NurbsCurveKnotList::SetKnot(int index, double k) { #if defined(ON_PYTHON_COMPILE) if (index >= Count() || index < 0) - throw pybind11::index_error("list index out of range"); + throw py::index_error("list index out of range"); #endif m_nurbs_curve->SetKnot(index, k); } diff --git a/src/bindings/bnd_nurbssurface.cpp b/src/bindings/bnd_nurbssurface.cpp index 74f42060..1daba63a 100644 --- a/src/bindings/bnd_nurbssurface.cpp +++ b/src/bindings/bnd_nurbssurface.cpp @@ -22,7 +22,7 @@ ON_4dPoint BND_NurbsSurfacePointList::GetControlPoint2(int u, int v) const #if defined(ON_PYTHON_COMPILE) if (u >= CountU() || v >= CountV() || u < 0 || v < 0) - throw pybind11::index_error("list index out of range"); + throw py::index_error("list index out of range"); #endif ON_4dPoint pt; m_surface->GetCV(u, v, pt); @@ -34,7 +34,7 @@ ON_3dPoint BND_NurbsSurfacePointList::GetPoint(int u, int v) const #if defined(ON_PYTHON_COMPILE) if (u >= CountU() || v >= CountV() || u < 0 || v < 0) - throw pybind11::index_error("list index out of range"); + throw py::index_error("list index out of range"); #endif ON_3dPoint pt; m_surface->GetCV(u, v, pt); @@ -54,7 +54,7 @@ void BND_NurbsSurfacePointList::SetControlPoint2(int u, int v, ON_4dPoint point) #if defined(ON_PYTHON_COMPILE) if (u >= CountU() || v >= CountV() || u < 0 || v < 0) - throw pybind11::index_error("list index out of range"); + throw py::index_error("list index out of range"); #endif m_surface->SetCV(u, v, point); } @@ -70,7 +70,7 @@ double BND_NurbsSurfaceKnotList::GetKnot(int index) const { #if defined(ON_PYTHON_COMPILE) if (index >= Count() || index < 0) - throw pybind11::index_error("list index out of range"); + throw py::index_error("list index out of range"); #endif return m_surface->Knot(m_direction, index); } @@ -79,7 +79,7 @@ void BND_NurbsSurfaceKnotList::SetKnot(int index, double k) { #if defined(ON_PYTHON_COMPILE) if (index >= Count() || index < 0) - throw pybind11::index_error("list index out of range"); + throw py::index_error("list index out of range"); #endif m_surface->SetKnot(m_direction, index, k); } diff --git a/src/bindings/bnd_object.cpp b/src/bindings/bnd_object.cpp index 49031736..6de55bea 100644 --- a/src/bindings/bnd_object.cpp +++ b/src/bindings/bnd_object.cpp @@ -5,7 +5,7 @@ std::string StringFromDict(BND_DICT& d, const char* key) { #if defined(ON_PYTHON_COMPILE) - std::string rc = pybind11::str(d[key]); + std::string rc = ToStdString(py::str(d[key])); #else std::string rc = d[key].as(); #endif @@ -15,7 +15,8 @@ std::string StringFromDict(BND_DICT& d, const char* key) int IntFromDict(BND_DICT& d, const char* key) { #if defined(ON_PYTHON_COMPILE) - int rc = d[key].cast(); +// int rc = d[key].cast(); + int rc = py::cast(d[key]); #else int rc = d[key].as(); #endif @@ -359,7 +360,7 @@ RH_C_FUNCTION ON_Write3dmBufferArchive* ON_WriteBufferArchive_NewMemoryWriter(in } #if defined(ON_PYTHON_COMPILE) -static bool WriteDictionaryEntryHelper(ON_Write3dmBufferArchive* archive, const ON_wString& key, ItemType it, pybind11::handle& value) +static bool WriteDictionaryEntryHelper(ON_Write3dmBufferArchive* archive, const ON_wString& key, ItemType it, py::handle& value) { if (ItemType::Undefined == it) return false; @@ -367,14 +368,14 @@ static bool WriteDictionaryEntryHelper(ON_Write3dmBufferArchive* archive, const if (!archive->BeginWriteDictionaryEntry((int)it, key)) return false; bool rc = false; - std::string s; + switch (it) { case ItemType::Undefined: break; case ItemType::Bool: { - bool b = value.cast(); + bool b = py::cast(value); rc = archive->WriteBool(b); } break; @@ -388,7 +389,7 @@ static bool WriteDictionaryEntryHelper(ON_Write3dmBufferArchive* archive, const break; case ItemType::Int32: { - int i = value.cast(); + int i = py::cast(value); rc = archive->WriteInt(i); } break; @@ -400,7 +401,7 @@ static bool WriteDictionaryEntryHelper(ON_Write3dmBufferArchive* archive, const break; case ItemType::Double: { - double d = value.cast(); + double d = py::cast(value); rc = archive->WriteDouble(d); } break; @@ -408,7 +409,7 @@ static bool WriteDictionaryEntryHelper(ON_Write3dmBufferArchive* archive, const break; case ItemType::String: { - s = pybind11::str(value); + std::string s = ToStdString(py::str(value)); ON_wString ws(s.c_str()); rc = archive->WriteString(ws); } @@ -451,31 +452,31 @@ static bool WriteDictionaryEntryHelper(ON_Write3dmBufferArchive* archive, const break; case ItemType::Point2d: { - ON_2dPoint pt = value.cast(); + ON_2dPoint pt = py::cast(value); rc = archive->WritePoint(pt); } break; case ItemType::Point3d: { - ON_3dPoint pt = value.cast(); + ON_3dPoint pt = py::cast(value); rc = archive->WritePoint(pt); } break; case ItemType::Point4d: { - ON_4dPoint pt = value.cast(); + ON_4dPoint pt = py::cast(value); rc = archive->WritePoint(pt); } break; case ItemType::Vector2d: { - ON_2dVector v = value.cast(); + ON_2dVector v = py::cast(value); rc = archive->WriteVector(v); } break; case ItemType::Vector3d: { - ON_3dVector v = value.cast(); + ON_3dVector v = py::cast(value); rc = archive->WriteVector(v); } break; @@ -503,7 +504,7 @@ static bool WriteDictionaryEntryHelper(ON_Write3dmBufferArchive* archive, const break; case ItemType::OnGeometry: { - BND_GeometryBase* geometry = value.cast(); + BND_GeometryBase* geometry = py::cast(value); rc = archive->WriteObject(*geometry->GeometryPointer()); } break; @@ -514,12 +515,12 @@ static bool WriteDictionaryEntryHelper(ON_Write3dmBufferArchive* archive, const case ItemType::ArrayGeometry: { int listCount = 0; - for (auto item : pybind11::iter(value)) + for (auto item : py::iter(value)) listCount++; rc = archive->WriteInt(listCount); - for (auto item : pybind11::iter(value)) + for (auto item : py::iter(value)) { - BND_GeometryBase* geometry = item.cast(); + BND_GeometryBase* geometry = py::cast(item); rc = rc && archive->WriteObject(*geometry->GeometryPointer()); } } @@ -530,9 +531,9 @@ static bool WriteDictionaryEntryHelper(ON_Write3dmBufferArchive* archive, const return archive->EndWriteDictionaryEntry() && rc; } -pybind11::dict BND_ArchivableDictionary::EncodeFromDictionary(pybind11::dict d) +py::dict BND_ArchivableDictionary::EncodeFromDictionary(py::dict d) { - pybind11::dict rc; + py::dict rc; int rhinoversion; SetupEncodedDictionaryVersions(rc, rhinoversion); @@ -545,55 +546,55 @@ pybind11::dict BND_ArchivableDictionary::EncodeFromDictionary(pybind11::dict d) for (auto item : d) { - std::string key(pybind11::str(item.first)); - ON_wString wkey(key.c_str()); + std::string s = ToStdString(py::str(item.first)); + ON_wString wkey(s.c_str()); ItemType it = ItemType::Undefined; - if (pybind11::bool_::check_(item.second)) + if (py::bool_::check_(item.second)) { it = ItemType::Bool; //1 } - else if (pybind11::int_::check_(item.second)) + else if (py::int_::check_(item.second)) { it = ItemType::Int32; //6 } - else if (pybind11::float_::check_(item.second)) + else if (py::float_::check_(item.second)) { it = ItemType::Double; //10 } - else if (pybind11::str::check_(item.second)) + else if (py::str::check_(item.second)) { it = ItemType::String; //12 } - else if (pybind11::isinstance(item.second)) + else if (py::isinstance(item.second)) { it = ItemType::Point2d; //31 } - else if (pybind11::isinstance(item.second)) + else if (py::isinstance(item.second)) { it = ItemType::Point3d; //32 } - else if (pybind11::isinstance(item.second)) + else if (py::isinstance(item.second)) { it = ItemType::Point4d; //33 } - else if (pybind11::isinstance(item.second)) + else if (py::isinstance(item.second)) { it = ItemType::Vector2d; //34 } - else if (pybind11::isinstance(item.second)) + else if (py::isinstance(item.second)) { it = ItemType::Vector3d; //35 } - else if (pybind11::isinstance(item.second)) + else if (py::isinstance(item.second)) { it = ItemType::OnGeometry; //47 } - else if (pybind11::isinstance(item.second)) + else if (py::isinstance(item.second)) { - for (auto listitem : pybind11::iter(item.second)) + for (auto listitem : py::iter(item.second)) { - bool isGeometry = pybind11::isinstance(listitem); + bool isGeometry = py::isinstance(listitem); if (!isGeometry) { it = ItemType::Undefined; @@ -611,13 +612,13 @@ pybind11::dict BND_ArchivableDictionary::EncodeFromDictionary(pybind11::dict d) msg += "\nAllowed value types are bool, int, float, str, Point2d, Point3d, Point4d,"; msg += "\nVector2d, Vector3d, and GeometryBase."; msg += "\nMore types can be supported; just ask."; - throw pybind11::cast_error(msg); + throw py::cast_error(); +// throw py::cast_error(msg); } if (ItemType::Undefined != it) WriteDictionaryEntryHelper(archive, wkey, it, item.second); } - pybind11::cast_error(""); archive->EndWriteDictionary(); std::string data = ""; @@ -916,7 +917,7 @@ BND_DICT BND_ArchivableDictionary::EncodeFromDictionary(BND_DICT dict) BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) { #if defined(ON_PYTHON_COMPILE) - pybind11::dict rc; + py::dict rc; #else emscripten::val rc(emscripten::val::object()); #endif @@ -929,7 +930,7 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) const unsigned char* c = (const unsigned char*)&decoded.at(0); // Eliminate potential bogus file versions written #if defined(ON_PYTHON_COMPILE) - pybind11::cast_error exception("Unable to decode ArchivableDictionary"); + py::cast_error exception();//("Unable to decode ArchivableDictionary"); if (rhinoversion > 5 && rhinoversion < 50) throw exception; @@ -1192,7 +1193,7 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) if (archive.ReadInt(2, i)) { #if defined(ON_PYTHON_COMPILE) - rc[keyname] = pybind11::make_tuple(i[0], i[1]); + rc[keyname] = py::make_tuple(i[0], i[1]); #else emscripten::val arr = emscripten::val::array(); arr.set(0,i[0]); @@ -1208,7 +1209,7 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) if (archive.ReadFloat(2, f)) { #if defined(ON_PYTHON_COMPILE) - rc[keyname] = pybind11::make_tuple(f[0], f[1]); + rc[keyname] = py::make_tuple(f[0], f[1]); #else emscripten::val arr = emscripten::val::array(); arr.set(0,f[0]); @@ -1224,7 +1225,7 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) if (archive.ReadInt(4, i)) { #if defined(ON_PYTHON_COMPILE) - rc[keyname] = pybind11::make_tuple(i[0], i[1], i[2], i[3]); + rc[keyname] = py::make_tuple(i[0], i[1], i[2], i[3]); #else emscripten::val arr = emscripten::val::array(); arr.set(0,i[0]); @@ -1242,7 +1243,7 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) if (archive.ReadFloat(4, f)) { #if defined(ON_PYTHON_COMPILE) - rc[keyname] = pybind11::make_tuple(f[0], f[1], f[2], f[3]); + rc[keyname] = py::make_tuple(f[0], f[1], f[2], f[3]); #else emscripten::val arr = emscripten::val::array(); arr.set(0,f[0]); @@ -1260,7 +1261,7 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) if (archive.ReadInt(2, i)) { #if defined(ON_PYTHON_COMPILE) - rc[keyname] = pybind11::make_tuple(i[0], i[1]); + rc[keyname] = py::make_tuple(i[0], i[1]); #else emscripten::val arr = emscripten::val::array(); arr.set(0,i[0]); @@ -1276,7 +1277,7 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) if (archive.ReadFloat(2, f)) { #if defined(ON_PYTHON_COMPILE) - rc[keyname] = pybind11::make_tuple(f[0], f[1]); + rc[keyname] = py::make_tuple(f[0], f[1]); #else emscripten::val arr = emscripten::val::array(); arr.set(0,f[0]); diff --git a/src/bindings/bnd_plane.cpp b/src/bindings/bnd_plane.cpp index 8596379d..01b1f19f 100644 --- a/src/bindings/bnd_plane.cpp +++ b/src/bindings/bnd_plane.cpp @@ -168,18 +168,28 @@ BND_DICT BND_Plane::Encode() const return d; } -BND_Plane* BND_Plane::Decode(pybind11::dict jsonObject) +BND_Plane* BND_Plane::Decode(py::dict jsonObject) { BND_Plane* rc = new BND_Plane(); - pybind11::dict d = jsonObject["Origin"].cast(); + py::dict d = py::cast(jsonObject["Origin"]); rc->m_origin = PointFromDict(d); - d = jsonObject["XAxis"].cast(); + d = py::cast(jsonObject["XAxis"]); rc->m_xaxis = PointFromDict(d); - d = jsonObject["YAxis"].cast(); + d = py::cast(jsonObject["YAxis"]); rc->m_yaxis = PointFromDict(d); - d = jsonObject["ZAxis"].cast(); + d = py::cast(jsonObject["ZAxis"]); rc->m_zaxis = PointFromDict(d); + /* + py::dict d = jsonObject["Origin"].cast(); + rc->m_origin = PointFromDict(d); + d = jsonObject["XAxis"].cast(); + rc->m_xaxis = PointFromDict(d); + d = jsonObject["YAxis"].cast(); + rc->m_yaxis = PointFromDict(d); + d = jsonObject["ZAxis"].cast(); + rc->m_zaxis = PointFromDict(d); + */ return rc; } #endif diff --git a/src/bindings/bnd_pointcloud.cpp b/src/bindings/bnd_pointcloud.cpp index 0e153a14..28ed24ee 100644 --- a/src/bindings/bnd_pointcloud.cpp +++ b/src/bindings/bnd_pointcloud.cpp @@ -196,7 +196,7 @@ BND_PointCloudItem BND_PointCloud::GetItem(int index) { #if defined(ON_PYTHON_COMPILE) if (index < 0 || index >= m_pointcloud->PointCount()) - throw pybind11::index_error(); + throw py::index_error(); #endif return BND_PointCloudItem(index, m_pointcloud, m_component_ref); diff --git a/src/bindings/bnd_polyline.cpp b/src/bindings/bnd_polyline.cpp index a9c2a24a..79a0fb44 100644 --- a/src/bindings/bnd_polyline.cpp +++ b/src/bindings/bnd_polyline.cpp @@ -41,7 +41,7 @@ ON_3dPoint BND_Point3dList::GetPoint(int index) const { #if defined(ON_PYTHON_COMPILE) if (index < 0 || index >= m_polyline.Count()) - throw pybind11::index_error(); + throw py::index_error(); #endif return m_polyline[index]; } diff --git a/src/bindings/bnd_render_content.cpp b/src/bindings/bnd_render_content.cpp index 91fbaaac..9ed235a7 100644 --- a/src/bindings/bnd_render_content.cpp +++ b/src/bindings/bnd_render_content.cpp @@ -4,7 +4,7 @@ BND_File3dmRenderContent::BND_File3dmRenderContent() { #if defined(ON_PYTHON_COMPILE) - throw pybind11::type_error("Unable to create an instance of RenderContent. Try creating RenderMaterial, RenderEnvironment, or RenderTexture"); + throw py::type_error("Unable to create an instance of RenderContent. Try creating RenderMaterial, RenderEnvironment, or RenderTexture"); #endif } @@ -13,7 +13,7 @@ BND_File3dmRenderContent::BND_File3dmRenderContent(ON_RenderContent* rc) if (nullptr == rc) { #if defined(ON_PYTHON_COMPILE) - throw pybind11::value_error("NULL RenderContent"); + throw py::value_error("NULL RenderContent"); #endif } diff --git a/src/bindings/bnd_sphere.cpp b/src/bindings/bnd_sphere.cpp index 517d9375..9ad01452 100644 --- a/src/bindings/bnd_sphere.cpp +++ b/src/bindings/bnd_sphere.cpp @@ -66,19 +66,21 @@ BND_NurbsSurface* BND_Sphere::ToNurbsSurface() const #if defined(ON_PYTHON_COMPILE) -pybind11::dict BND_Sphere::Encode() const +py::dict BND_Sphere::Encode() const { - pybind11::dict d; + py::dict d; d["Radius"] = m_sphere.radius; d["EquatorialPlane"] = PlaneToDict(m_sphere.plane); return d; } -BND_Sphere* BND_Sphere::Decode(pybind11::dict jsonObject) +BND_Sphere* BND_Sphere::Decode(py::dict jsonObject) { ON_Sphere s; - s.radius = jsonObject["Radius"].cast(); - pybind11::dict d = jsonObject["EquatorialPlane"].cast(); +// s.radius = jsonObject["Radius"].cast(); +// py::dict d = jsonObject["EquatorialPlane"].cast(); + s.radius = py::cast(jsonObject["Radius"]); + py::dict d = py::cast(jsonObject["EquatorialPlane"]); s.plane = PlaneFromDict(d); return new BND_Sphere(s); } diff --git a/src/bindings/bnd_texture.cpp b/src/bindings/bnd_texture.cpp index 102a2189..37428f77 100644 --- a/src/bindings/bnd_texture.cpp +++ b/src/bindings/bnd_texture.cpp @@ -113,8 +113,7 @@ void initEnvironmentBindings(void*) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -namespace py = pybind11; -void initTextureBindings(pybind11::module& m) +void initTextureBindings(py::module_& m) { py::enum_(m, "TextureType") .value("None", ON_Texture::TYPE::no_texture_type) diff --git a/src/bindings/bnd_viewport.cpp b/src/bindings/bnd_viewport.cpp index bfd689e3..7654b321 100644 --- a/src/bindings/bnd_viewport.cpp +++ b/src/bindings/bnd_viewport.cpp @@ -149,10 +149,10 @@ emscripten::val BND_Viewport::GetFrustum() const void BND_Viewport::SetScreenPort(BND_TUPLE rect) { #if defined(ON_PYTHON_COMPILE) - int x = rect[0].cast(); - int y = rect[1].cast(); - int width = rect[2].cast(); - int height = rect[3].cast(); + int x = py::cast(rect[0]); + int y = py::cast(rect[1]); + int width = py::cast(rect[2]); + int height = py::cast(rect[3]); m_viewport->SetScreenPort(x, x + width, y + height, y); #else int x = rect[0].as(); diff --git a/src/create_python_vcxproj.py b/src/create_python_vcxproj.py index 5f98a9b1..5a7abbd9 100644 --- a/src/create_python_vcxproj.py +++ b/src/create_python_vcxproj.py @@ -33,7 +33,7 @@ def createproject(): print(line.replace("WIN32;", "WIN64;")) #os.system("cmake --build . --config Release --target _rhino3dm") else: - rv = os.system("cmake -DPYTHON_EXECUTABLE:FILEPATH={} ../..".format(sys.executable)) + rv = os.system('cmake -G "Xcode" -DPYTHON_EXECUTABLE:FILEPATH={} ../..'.format(sys.executable)) if int(rv) > 0: sys.exit(1) #rv = os.system("make") #if int(rv) > 0: sys.exit(1) From e80d14388459bc89fe8f7eef50de10bf7e0db1b2 Mon Sep 17 00:00:00 2001 From: fraguada Date: Tue, 6 Aug 2024 11:55:09 +0200 Subject: [PATCH 07/27] cleanup bindings --- src/bindings/bindings.cpp | 2 +- src/bindings/bindings.h | 6 +++++- src/bindings/bnd_3dm_attributes.cpp | 10 +++------- src/bindings/bnd_3dm_attributes.h | 11 +---------- src/bindings/bnd_3dm_settings.cpp | 9 ++------- src/bindings/bnd_3dm_settings.h | 9 +-------- src/bindings/bnd_annotationbase.cpp | 6 +----- src/bindings/bnd_annotationbase.h | 9 +-------- src/bindings/bnd_arc.cpp | 9 +-------- src/bindings/bnd_arc.h | 9 +-------- src/bindings/bnd_arccurve.cpp | 8 +------- src/bindings/bnd_arccurve.h | 9 +-------- src/bindings/bnd_beam.cpp | 8 +------- src/bindings/bnd_beam.h | 9 +-------- src/bindings/bnd_bezier.cpp | 9 ++------- src/bindings/bnd_bezier.h | 9 +-------- src/bindings/bnd_bitmap.cpp | 9 ++------- src/bindings/bnd_bitmap.h | 9 +-------- src/bindings/bnd_boundingbox.cpp | 7 ++----- src/bindings/bnd_boundingbox.h | 9 +-------- src/bindings/bnd_box.cpp | 9 ++------- src/bindings/bnd_box.h | 9 +-------- src/bindings/bnd_brep.cpp | 8 +++----- src/bindings/bnd_brep.h | 11 +---------- src/bindings/bnd_circle.cpp | 10 +++------- src/bindings/bnd_circle.h | 9 +-------- src/bindings/bnd_cone.cpp | 9 ++------- src/bindings/bnd_cone.h | 9 +-------- src/bindings/bnd_curve.cpp | 9 ++------- src/bindings/bnd_curve.h | 9 +-------- src/bindings/bnd_curveproxy.cpp | 10 +++------- src/bindings/bnd_curveproxy.h | 9 +-------- src/bindings/bnd_cylinder.cpp | 9 ++------- src/bindings/bnd_cylinder.h | 9 +-------- src/bindings/bnd_decals.cpp | 10 +++------- src/bindings/bnd_decals.h | 9 +-------- src/bindings/bnd_defines.cpp | 24 ++++++++++-------------- src/bindings/bnd_defines.h | 5 +---- src/bindings/bnd_dimensionstyle.cpp | 10 +++------- src/bindings/bnd_dimensionstyle.h | 9 +-------- src/bindings/bnd_dithering.cpp | 10 +++------- src/bindings/bnd_dithering.h | 9 +-------- src/bindings/bnd_draco.cpp | 12 +++++------- src/bindings/bnd_draco.h | 9 +-------- src/bindings/bnd_ellipse.cpp | 10 +++------- src/bindings/bnd_ellipse.h | 9 +-------- src/bindings/bnd_embedded_file.cpp | 10 +++------- src/bindings/bnd_embedded_file.h | 9 +-------- src/bindings/bnd_extensions.h | 9 +-------- src/bindings/bnd_file_utilities.h | 9 +-------- src/bindings/bnd_font.cpp | 10 +++------- src/bindings/bnd_font.h | 9 +-------- src/bindings/bnd_geometry.cpp | 10 +++------- src/bindings/bnd_geometry.h | 9 +-------- src/bindings/bnd_ground_plane.cpp | 10 +++------- src/bindings/bnd_ground_plane.h | 9 +-------- src/bindings/bnd_group.cpp | 10 +++------- src/bindings/bnd_group.h | 9 +-------- src/bindings/bnd_hatch.cpp | 10 +++------- src/bindings/bnd_hatch.h | 9 +-------- src/bindings/bnd_instance.cpp | 10 +++------- src/bindings/bnd_instance.h | 9 +-------- src/bindings/bnd_intersect.h | 9 +-------- src/bindings/bnd_layer.cpp | 10 +++------- src/bindings/bnd_layer.h | 9 +-------- src/bindings/bnd_light.cpp | 10 +++------- src/bindings/bnd_light.h | 9 +-------- src/bindings/bnd_linear_workflow.cpp | 10 +++------- src/bindings/bnd_linear_workflow.h | 9 +-------- src/bindings/bnd_linecurve.cpp | 10 +++------- src/bindings/bnd_linecurve.h | 9 +-------- src/bindings/bnd_linetype.cpp | 10 +++------- src/bindings/bnd_linetype.h | 9 +-------- src/bindings/bnd_material.cpp | 10 +++------- src/bindings/bnd_material.h | 9 +-------- src/bindings/bnd_mesh.cpp | 10 +++------- src/bindings/bnd_mesh.h | 9 +-------- src/bindings/bnd_mesh_modifiers.cpp | 10 +++------- src/bindings/bnd_mesh_modifiers.h | 9 +-------- src/bindings/bnd_model_component.cpp | 10 +++------- src/bindings/bnd_model_component.h | 9 +-------- src/bindings/bnd_nurbscurve.cpp | 18 +++++++++--------- src/bindings/bnd_nurbscurve.h | 9 +-------- src/bindings/bnd_nurbssurface.cpp | 18 +++++++++--------- src/bindings/bnd_nurbssurface.h | 9 +-------- src/bindings/bnd_object.cpp | 24 ++++++++++-------------- src/bindings/bnd_object.h | 9 +-------- src/bindings/bnd_plane.cpp | 10 +++------- src/bindings/bnd_plane.h | 9 +-------- src/bindings/bnd_planesurface.cpp | 10 +++------- src/bindings/bnd_planesurface.h | 9 +-------- src/bindings/bnd_point.cpp | 2 +- src/bindings/bnd_point.h | 9 +-------- src/bindings/bnd_pointcloud.cpp | 10 +++------- src/bindings/bnd_pointcloud.h | 9 +-------- src/bindings/bnd_pointgeometry.cpp | 10 +++------- src/bindings/bnd_pointgeometry.h | 9 +-------- src/bindings/bnd_pointgrid.cpp | 10 +++------- src/bindings/bnd_pointgrid.h | 9 +-------- src/bindings/bnd_polycurve.cpp | 10 +++------- src/bindings/bnd_polycurve.h | 9 +-------- src/bindings/bnd_polyline.cpp | 10 +++------- src/bindings/bnd_polyline.h | 9 +-------- src/bindings/bnd_polylinecurve.cpp | 10 +++------- src/bindings/bnd_polylinecurve.h | 9 +-------- src/bindings/bnd_post_effects.cpp | 10 +++------- src/bindings/bnd_post_effects.h | 9 +-------- src/bindings/bnd_render_channels.cpp | 10 +++------- src/bindings/bnd_render_channels.h | 9 +-------- src/bindings/bnd_render_content.cpp | 10 +++------- src/bindings/bnd_render_content.h | 9 +-------- src/bindings/bnd_render_environments.cpp | 10 +++------- src/bindings/bnd_render_environments.h | 9 +-------- src/bindings/bnd_revsurface.cpp | 10 +++------- src/bindings/bnd_revsurface.h | 9 +-------- src/bindings/bnd_rtree.cpp | 10 +++------- src/bindings/bnd_rtree.h | 9 +-------- src/bindings/bnd_safe_frame.cpp | 10 +++------- src/bindings/bnd_safe_frame.h | 9 +-------- src/bindings/bnd_skylight.cpp | 10 +++------- src/bindings/bnd_skylight.h | 9 +-------- src/bindings/bnd_sphere.cpp | 10 +++------- src/bindings/bnd_sphere.h | 9 +-------- src/bindings/bnd_subd.cpp | 10 +++------- src/bindings/bnd_subd.h | 9 +-------- src/bindings/bnd_sun.cpp | 10 +++------- src/bindings/bnd_sun.h | 9 +-------- src/bindings/bnd_surface.cpp | 10 +++------- src/bindings/bnd_surface.h | 9 +-------- src/bindings/bnd_surfaceproxy.cpp | 10 +++------- src/bindings/bnd_surfaceproxy.h | 9 +-------- src/bindings/bnd_texture.cpp | 10 +++------- src/bindings/bnd_texture.h | 12 ++---------- src/bindings/bnd_texture_mapping.cpp | 10 +++------- src/bindings/bnd_texture_mapping.h | 9 +-------- src/bindings/bnd_viewport.cpp | 7 ++----- src/bindings/bnd_viewport.h | 9 +-------- src/bindings/bnd_xform.cpp | 10 +++------- src/bindings/bnd_xform.h | 9 +-------- 139 files changed, 287 insertions(+), 1038 deletions(-) diff --git a/src/bindings/bindings.cpp b/src/bindings/bindings.cpp index 7d02a747..554affc3 100644 --- a/src/bindings/bindings.cpp +++ b/src/bindings/bindings.cpp @@ -91,7 +91,7 @@ EMSCRIPTEN_BINDINGS(rhino3dm) { #if defined(ON_PYTHON_COMPILE) std::string ToStdString(const py::str& str) { - std::string rc = str; + std::string rc = py::cast(str); return rc; } #endif diff --git a/src/bindings/bindings.h b/src/bindings/bindings.h index 59df0167..00d36e94 100644 --- a/src/bindings/bindings.h +++ b/src/bindings/bindings.h @@ -16,6 +16,9 @@ #define RH3DM_PYTHON_BINDING(name, variable) NB_MODULE(name, variable) #define def_property def_prop_rw #define def_property_readonly def_prop_ro +#define def_readonly def_ro +#define def_readwrite def_rw +#define def_property_readonly_static def_prop_ro_static #define UNIMPLEMENTED_EXCEPTION throw std::exception() #else @@ -23,7 +26,7 @@ #include namespace py = pybind11; #define RH3DM_PYTHON_BINDING(name, variable) PYBIND11_MODULE(name, variable) - typedef pybind11::module_ rh3dmpymodule; + typedef pybind11::module rh3dmpymodule; #endif std::string ToStdString(const py::str& str); @@ -44,6 +47,7 @@ typedef py::tuple BND_Color; typedef py::tuple BND_Color4f; typedef py::tuple BND_TUPLE; typedef py::handle BND_DateTime; +typedef py::list BND_LIST; #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_3dm_attributes.cpp b/src/bindings/bnd_3dm_attributes.cpp index ef98409d..eb6f815c 100644 --- a/src/bindings/bnd_3dm_attributes.cpp +++ b/src/bindings/bnd_3dm_attributes.cpp @@ -109,12 +109,8 @@ BND_TUPLE BND_3dmObjectAttributes::GetGroupList() const ////////////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void init3dmAttributesBindings(py::module_& m){} -#else -namespace py = pybind11; -void init3dmAttributesBindings(py::module& m) + +void init3dmAttributesBindings(rh3dmpymodule& m) { py::class_(m, "ObjectAttributes") @@ -155,7 +151,7 @@ void init3dmAttributesBindings(py::module& m) .def("RemoveFromAllGroups", &BND_3dmObjectAttributes::RemoveFromAllGroups) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_3dm_attributes.h b/src/bindings/bnd_3dm_attributes.h index db6c9d91..e12e7d8a 100644 --- a/src/bindings/bnd_3dm_attributes.h +++ b/src/bindings/bnd_3dm_attributes.h @@ -3,16 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) - -#if defined(NANOBIND) -namespace py = nanobind; -void init3dmAttributesBindings(py::module_& m); -#else -namespace py = pybind11; -void init3dmAttributesBindings(py::module& m); -#endif - - +void init3dmAttributesBindings(rh3dmpymodule& m); #else void init3dmAttributesBindings(void* m); #endif diff --git a/src/bindings/bnd_3dm_settings.cpp b/src/bindings/bnd_3dm_settings.cpp index ef100080..7e1561a5 100644 --- a/src/bindings/bnd_3dm_settings.cpp +++ b/src/bindings/bnd_3dm_settings.cpp @@ -122,13 +122,8 @@ void BND_File3dmSettings::SetEarthAnchorPoint(const BND_EarthAnchorPoint& anchor } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void init3dmSettingsBindings(py::module_& m){} -#else -namespace py = pybind11; -void init3dmSettingsBindings(py::module& m) +void init3dmSettingsBindings(rh3dmpymodule& m) { py::class_(m, "ConstructionPlane") .def(py::init<>()) @@ -220,7 +215,7 @@ void init3dmSettingsBindings(py::module& m) .def_property_readonly("RenderSettings", &BND_File3dmSettings::GetRenderSettings) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_3dm_settings.h b/src/bindings/bnd_3dm_settings.h index cee6561c..49d3e550 100644 --- a/src/bindings/bnd_3dm_settings.h +++ b/src/bindings/bnd_3dm_settings.h @@ -4,14 +4,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void init3dmSettingsBindings(py::module_& m); -#else -namespace py = pybind11; -void init3dmSettingsBindings(py::module& m); -#endif - +void init3dmSettingsBindings(rh3dmpymodule& m); #else void init3dmSettingsBindings(void* m); #endif diff --git a/src/bindings/bnd_annotationbase.cpp b/src/bindings/bnd_annotationbase.cpp index c1dbaf9f..c7bcf46f 100644 --- a/src/bindings/bnd_annotationbase.cpp +++ b/src/bindings/bnd_annotationbase.cpp @@ -630,10 +630,7 @@ std::vector BND_Centermark::GetDisplayLines(const BND_DimensionStyle& d #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -void initAnnotationBaseBindings(py::module_& m){} -#else -void initAnnotationBaseBindings(py::module& m) +void initAnnotationBaseBindings(rh3dmpymodule& m) { py::class_(m, "AnnotationBase") .def_property_readonly("DimensionStyleId", &BND_AnnotationBase::DimensionStyleId) @@ -691,7 +688,6 @@ void initAnnotationBaseBindings(py::module& m) } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_annotationbase.h b/src/bindings/bnd_annotationbase.h index d0708b55..fdc9b147 100644 --- a/src/bindings/bnd_annotationbase.h +++ b/src/bindings/bnd_annotationbase.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initAnnotationBaseBindings(py::module_& m); -#else -namespace py = pybind11; -void initAnnotationBaseBindings(py::module& m); -#endif - +void initAnnotationBaseBindings(rh3dmpymodule& m); #else void initAnnotationBaseBindings(void* m); #endif diff --git a/src/bindings/bnd_arc.cpp b/src/bindings/bnd_arc.cpp index 0158bdb8..70c1210c 100644 --- a/src/bindings/bnd_arc.cpp +++ b/src/bindings/bnd_arc.cpp @@ -125,13 +125,7 @@ BND_NurbsCurve* BND_Arc::ToNurbsCurve() const #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initArcBindings(py::module_& m){} -#else -namespace py = pybind11; -void initArcBindings(py::module& m) - +void initArcBindings(rh3dmpymodule& m) { py::class_(m, "Arc") .def(py::init(), py::arg("circle"), py::arg("angleRadians")) @@ -167,7 +161,6 @@ void initArcBindings(py::module& m) .def("ToNurbsCurve", &BND_Arc::ToNurbsCurve); } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_arc.h b/src/bindings/bnd_arc.h index 92cde0f6..311ac5c0 100644 --- a/src/bindings/bnd_arc.h +++ b/src/bindings/bnd_arc.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initArcBindings(py::module_& m); -#else -namespace py = pybind11; -void initArcBindings(py::module& m); -#endif - +void initArcBindings(rh3dmpymodule& m); #else void initArcBindings(void* m); #endif diff --git a/src/bindings/bnd_arccurve.cpp b/src/bindings/bnd_arccurve.cpp index ba04af70..c4decdc2 100644 --- a/src/bindings/bnd_arccurve.cpp +++ b/src/bindings/bnd_arccurve.cpp @@ -51,12 +51,7 @@ void BND_ArcCurve::SetTrackedPointer(ON_ArcCurve* arccurve, const ON_ModelCompon #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initArcCurveBindings(py::module_& m){} -#else -namespace py = pybind11; -void initArcCurveBindings(py::module& m) +void initArcCurveBindings(rh3dmpymodule& m) { py::class_(m, "ArcCurve") .def_static("CreateFromArc", &BND_ArcCurve::CreateFromArc, py::arg("arc")) @@ -73,7 +68,6 @@ void initArcCurveBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_arccurve.h b/src/bindings/bnd_arccurve.h index 8f52b29a..a05ff265 100644 --- a/src/bindings/bnd_arccurve.h +++ b/src/bindings/bnd_arccurve.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initArcCurveBindings(py::module_& m); -#else -namespace py = pybind11; -void initArcCurveBindings(py::module& m); -#endif - +void initArcCurveBindings(rh3dmpymodule& m); #else void initArcCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_beam.cpp b/src/bindings/bnd_beam.cpp index 100a07a8..5cde50ca 100644 --- a/src/bindings/bnd_beam.cpp +++ b/src/bindings/bnd_beam.cpp @@ -192,13 +192,8 @@ BND_Extrusion::BND_Extrusion(ON_Extrusion* extrusion, const ON_ModelComponentRef ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initExtrusionBindings(py::module_& m){} -#else -namespace py = pybind11; -void initExtrusionBindings(py::module& m) +void initExtrusionBindings(rh3dmpymodule& m) { py::class_(m, "Extrusion") .def_static("Create", &BND_Extrusion::Create, py::arg("planarCurve"), py::arg("height"), py::arg("cap")) @@ -236,7 +231,6 @@ void initExtrusionBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_beam.h b/src/bindings/bnd_beam.h index a6ff472e..452fe735 100644 --- a/src/bindings/bnd_beam.h +++ b/src/bindings/bnd_beam.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initExtrusionBindings(py::module_& m); -#else -namespace py = pybind11; -void initExtrusionBindings(py::module& m); -#endif - +void initExtrusionBindings(rh3dmpymodule& m); #else void initExtrusionBindings(void* m); #endif diff --git a/src/bindings/bnd_bezier.cpp b/src/bindings/bnd_bezier.cpp index d5480d64..af480c29 100644 --- a/src/bindings/bnd_bezier.cpp +++ b/src/bindings/bnd_bezier.cpp @@ -32,12 +32,8 @@ BND_TUPLE BND_BezierCurve::Split(double t) #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initBezierBindings(py::module_& m){} -#else -namespace py = pybind11; -void initBezierBindings(py::module& m) + +void initBezierBindings(rh3dmpymodule& m) { py::class_(m, "BezierCurve") .def_property_readonly("Dimension", &BND_BezierCurve::Dimension) @@ -56,7 +52,6 @@ void initBezierBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_bezier.h b/src/bindings/bnd_bezier.h index 87aa8372..908681a2 100644 --- a/src/bindings/bnd_bezier.h +++ b/src/bindings/bnd_bezier.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initBezierBindings(py::module_& m); -#else -namespace py = pybind11; -void initBezierBindings(py::module& m); -#endif - +void initBezierBindings(rh3dmpymodule& m); #else void initBezierBindings(void* m); #endif diff --git a/src/bindings/bnd_bitmap.cpp b/src/bindings/bnd_bitmap.cpp index ac132475..677b7cf4 100644 --- a/src/bindings/bnd_bitmap.cpp +++ b/src/bindings/bnd_bitmap.cpp @@ -17,12 +17,8 @@ void BND_Bitmap::SetTrackedPointer(ON_Bitmap* bitmap, const ON_ModelComponentRef #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initBitmapBindings(py::module_& m){} -#else -namespace py = pybind11; -void initBitmapBindings(py::module& m) + +void initBitmapBindings(rh3dmpymodule& m) { py::class_(m, "Bitmap") .def(py::init<>()) @@ -34,7 +30,6 @@ void initBitmapBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_bitmap.h b/src/bindings/bnd_bitmap.h index 73dcd226..53bfecbd 100644 --- a/src/bindings/bnd_bitmap.h +++ b/src/bindings/bnd_bitmap.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initBitmapBindings(py::module_& m); -#else -namespace py = pybind11; -void initBitmapBindings(py::module& m); -#endif - +void initBitmapBindings(rh3dmpymodule& m); #else void initBitmapBindings(void* m); #endif diff --git a/src/bindings/bnd_boundingbox.cpp b/src/bindings/bnd_boundingbox.cpp index bb8cb1c3..8d39e3cf 100644 --- a/src/bindings/bnd_boundingbox.cpp +++ b/src/bindings/bnd_boundingbox.cpp @@ -161,10 +161,8 @@ BND_BoundingBox* BND_BoundingBox::Decode(emscripten::val jsonObject) #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -void initBoundingBoxBindings(py::module_& m){} -#else -void initBoundingBoxBindings(py::module& m) + +void initBoundingBoxBindings(rh3dmpymodule& m) { py::class_(m, "BoundingBox") .def(py::init(), py::arg("minPoint"), py::arg("maxPoint")) @@ -189,7 +187,6 @@ void initBoundingBoxBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_boundingbox.h b/src/bindings/bnd_boundingbox.h index 85b57da4..4aa1aecf 100644 --- a/src/bindings/bnd_boundingbox.h +++ b/src/bindings/bnd_boundingbox.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initBoundingBoxBindings(py::module_& m); -#else -namespace py = pybind11; -void initBoundingBoxBindings(py::module& m); -#endif - +void initBoundingBoxBindings(rh3dmpymodule& m); #else void initBoundingBoxBindings(void* m); #endif diff --git a/src/bindings/bnd_box.cpp b/src/bindings/bnd_box.cpp index 7a43ee0a..a30051cb 100644 --- a/src/bindings/bnd_box.cpp +++ b/src/bindings/bnd_box.cpp @@ -29,12 +29,8 @@ ON_3dPoint BND_Box::PointAt(double x, double y, double z) const //} #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initBoxBindings(py::module_& m){} -#else -namespace py = pybind11; -void initBoxBindings(py::module& m) + +void initBoxBindings(rh3dmpymodule& m) { py::class_(m, "Box") .def(py::init(), py::arg("bbox")) @@ -48,7 +44,6 @@ void initBoxBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_box.h b/src/bindings/bnd_box.h index a0818e25..0d39cc1f 100644 --- a/src/bindings/bnd_box.h +++ b/src/bindings/bnd_box.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initBoxBindings(py::module_& m); -#else -namespace py = pybind11; -void initBoxBindings(py::module& m); -#endif - +void initBoxBindings(rh3dmpymodule& m); #else void initBoxBindings(void* m); #endif diff --git a/src/bindings/bnd_brep.cpp b/src/bindings/bnd_brep.cpp index 995b321c..f3d75360 100644 --- a/src/bindings/bnd_brep.cpp +++ b/src/bindings/bnd_brep.cpp @@ -384,10 +384,8 @@ BND_TUPLE BND_BrepVertex::EdgeIndices() const { ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -void initBrepBindings(py::module_& m){} -#else -void initBrepBindings(py::module& m) + +void initBrepBindings(rh3dmpymodule& m) { py::class_(m, "BrepEdge") ; @@ -451,7 +449,7 @@ void initBrepBindings(py::module& m) .def("Flip", &BND_Brep::Flip) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_brep.h b/src/bindings/bnd_brep.h index 60f8a24a..e3482588 100644 --- a/src/bindings/bnd_brep.h +++ b/src/bindings/bnd_brep.h @@ -2,16 +2,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) - -#if defined(NANOBIND) -namespace py = nanobind; -void initBrepBindings(py::module_& m); -#else -namespace py = pybind11; -void initBrepBindings(py::module& m); -#endif - - +void initBrepBindings(rh3dmpymodule& m); #else void initBrepBindings(void* m); #endif diff --git a/src/bindings/bnd_circle.cpp b/src/bindings/bnd_circle.cpp index 3adef6e7..7eeaa921 100644 --- a/src/bindings/bnd_circle.cpp +++ b/src/bindings/bnd_circle.cpp @@ -95,12 +95,8 @@ BND_DICT BND_Circle::Encode() const #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initCircleBindings(py::module_& m){} -#else -namespace py = pybind11; -void initCircleBindings(py::module& m) + +void initCircleBindings(rh3dmpymodule& m) { py::class_(m, "Circle") .def(py::init(), py::arg("radius")) @@ -126,7 +122,7 @@ void initCircleBindings(py::module& m) .def("Encode", &BND_Circle::Encode) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_circle.h b/src/bindings/bnd_circle.h index ceade6e3..4bb29e0f 100644 --- a/src/bindings/bnd_circle.h +++ b/src/bindings/bnd_circle.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initCircleBindings(py::module_& m); -#else -namespace py = pybind11; -void initCircleBindings(py::module& m); -#endif - +void initCircleBindings(rh3dmpymodule& m); #else void initCircleBindings(void* m); #endif diff --git a/src/bindings/bnd_cone.cpp b/src/bindings/bnd_cone.cpp index df638606..0095f393 100644 --- a/src/bindings/bnd_cone.cpp +++ b/src/bindings/bnd_cone.cpp @@ -20,12 +20,8 @@ BND_Brep* BND_Cone::ToBrep(bool capBottom) const } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initConeBindings(py::module_& m){} -#else -namespace py = pybind11; -void initConeBindings(py::module& m) + +void initConeBindings(rh3dmpymodule& m) { py::class_(m, "Cone") .def_property("Height", &BND_Cone::GetHeight, &BND_Cone::SetHeight) @@ -41,7 +37,6 @@ void initConeBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_cone.h b/src/bindings/bnd_cone.h index 882688ce..b95b9caf 100644 --- a/src/bindings/bnd_cone.h +++ b/src/bindings/bnd_cone.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initConeBindings(py::module_& m); -#else -namespace py = pybind11; -void initConeBindings(py::module& m); -#endif - +void initConeBindings(rh3dmpymodule& m); #else void initConeBindings(void* m); #endif diff --git a/src/bindings/bnd_curve.cpp b/src/bindings/bnd_curve.cpp index 5aa7c82e..019b5465 100644 --- a/src/bindings/bnd_curve.cpp +++ b/src/bindings/bnd_curve.cpp @@ -252,12 +252,8 @@ BND_NurbsCurve* BND_Curve::ToNurbsCurve2(BND_Interval subdomain) const #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initCurveBindings(py::module_& m){} -#else -namespace py = pybind11; -void initCurveBindings(py::module& m) + +void initCurveBindings(rh3dmpymodule& m) { py::enum_(m, "CurveEvaluationSide") .value("Default", CurveEvaluationSide::Default) @@ -360,7 +356,6 @@ void initCurveBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_curve.h b/src/bindings/bnd_curve.h index 31c55373..64f7b13f 100644 --- a/src/bindings/bnd_curve.h +++ b/src/bindings/bnd_curve.h @@ -67,14 +67,7 @@ enum class CurveEvaluationSide : int #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initCurveBindings(py::module_& m); -#else -namespace py = pybind11; -void initCurveBindings(py::module& m); -#endif - +void initCurveBindings(rh3dmpymodule& m); #else void initCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_curveproxy.cpp b/src/bindings/bnd_curveproxy.cpp index 29578f54..2e8a7d75 100644 --- a/src/bindings/bnd_curveproxy.cpp +++ b/src/bindings/bnd_curveproxy.cpp @@ -14,18 +14,14 @@ void BND_CurveProxy::SetTrackedPointer(ON_CurveProxy* curveproxy, const ON_Model ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initCurveProxyBindings(py::module_& m){} -#else -namespace py = pybind11; -void initCurveProxyBindings(py::module& m) + +void initCurveProxyBindings(rh3dmpymodule& m) { py::class_(m, "CurveProxy") .def_property_readonly("ProxyCurveIsReversed", &BND_CurveProxy::ProxyCurveIsReversed) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_curveproxy.h b/src/bindings/bnd_curveproxy.h index fadbe8fb..6b51c1d5 100644 --- a/src/bindings/bnd_curveproxy.h +++ b/src/bindings/bnd_curveproxy.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initCurveProxyBindings(py::module_& m); -#else -namespace py = pybind11; -void initCurveProxyBindings(py::module& m); -#endif - +void initCurveProxyBindings(rh3dmpymodule& m); #else void initCurveProxyBindings(void* m); #endif diff --git a/src/bindings/bnd_cylinder.cpp b/src/bindings/bnd_cylinder.cpp index 16238d4e..3849214d 100644 --- a/src/bindings/bnd_cylinder.cpp +++ b/src/bindings/bnd_cylinder.cpp @@ -42,12 +42,8 @@ BND_NurbsSurface* BND_Cylinder::ToNurbsSurface() const #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initCylinderBindings(py::module_& m){} -#else -namespace py = pybind11; -void initCylinderBindings(py::module& m) + +void initCylinderBindings(rh3dmpymodule& m) { py::class_(m, "Cylinder") .def(py::init(), py::arg("baseCircle")) @@ -66,7 +62,6 @@ void initCylinderBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_cylinder.h b/src/bindings/bnd_cylinder.h index 9a64e00f..e8ff63e6 100644 --- a/src/bindings/bnd_cylinder.h +++ b/src/bindings/bnd_cylinder.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initCylinderBindings(py::module_& m); -#else -namespace py = pybind11; -void initCylinderBindings(py::module& m); -#endif - +void initCylinderBindings(rh3dmpymodule& m); #else void initCylinderBindings(void* m); #endif diff --git a/src/bindings/bnd_decals.cpp b/src/bindings/bnd_decals.cpp index 28bf96e2..55b42e9c 100644 --- a/src/bindings/bnd_decals.cpp +++ b/src/bindings/bnd_decals.cpp @@ -279,12 +279,8 @@ BND_File3dmDecal* BND_File3dmDecalTable::IterIndex(int index) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initDecalBindings(py::module_& m){} -#else -namespace py = pybind11; -void initDecalBindings(py::module& m) + +void initDecalBindings(rh3dmpymodule& m) { py::enum_(m, "Mappings") .value("None", Mappings::None) @@ -324,7 +320,7 @@ void initDecalBindings(py::module& m) .def_property("BoundsMaxV", &BND_File3dmDecal::BoundsMaxV, &BND_File3dmDecal::SetBoundsMaxV) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_decals.h b/src/bindings/bnd_decals.h index a2f05779..8bfb9dee 100644 --- a/src/bindings/bnd_decals.h +++ b/src/bindings/bnd_decals.h @@ -20,14 +20,7 @@ enum class Projections : int }; #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initDecalBindings(py::module_& m); -#else -namespace py = pybind11; -void initDecalBindings(py::module& m); -#endif - +void initDecalBindings(rh3dmpymodule& m); #else void initDecalBindings(void* m); #endif diff --git a/src/bindings/bnd_defines.cpp b/src/bindings/bnd_defines.cpp index 11afb61f..29926851 100644 --- a/src/bindings/bnd_defines.cpp +++ b/src/bindings/bnd_defines.cpp @@ -29,12 +29,8 @@ static std::vector ArrowPoints(ON_Arrowhead::arrow_type arrowType, d } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initDefines(py::module_& m){} -#else -namespace py = pybind11; -void initDefines(py::module& m) + +void initDefines(rh3dmpymodule& m) { py::enum_(m, "ComponentIndexType") .value("InvalidType", ON_COMPONENT_INDEX::TYPE::invalid_type) @@ -349,9 +345,9 @@ py::dict PlaneToDict(const ON_Plane& plane) ON_3dPoint PointFromDict(py::dict& dict) { ON_3dVector rc; - rc.x = dict["X"].cast(); - rc.y = dict["Y"].cast(); - rc.z = dict["Z"].cast(); + rc.x = py::cast(dict["X"]); + rc.y = py::cast(dict["Y"]); + rc.z = py::cast(dict["Z"]); return rc; } ON_3dVector VectorFromDict(py::dict& dict) @@ -362,18 +358,18 @@ ON_3dVector VectorFromDict(py::dict& dict) ON_Plane PlaneFromDict(py::dict& dict) { ON_Plane plane; - py::dict d = dict["Origin"].cast(); + py::dict d = dict["Origin"]; plane.origin = PointFromDict(d); - d = dict["XAxis"].cast(); + d = dict["XAxis"]; plane.xaxis = VectorFromDict(d); - d = dict["YAxis"].cast(); + d = dict["YAxis"]; plane.yaxis = VectorFromDict(d); - d = dict["ZAxis"].cast(); + d = dict["ZAxis"]; plane.zaxis = VectorFromDict(d); plane.UpdateEquation(); return plane; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_defines.h b/src/bindings/bnd_defines.h index cd07cb1b..a6c84ee8 100644 --- a/src/bindings/bnd_defines.h +++ b/src/bindings/bnd_defines.h @@ -7,13 +7,10 @@ #if defined(NANOBIND) namespace py = nanobind; -void initDefines(py::module_& m); #else namespace py = pybind11; -void initDefines(py::module& m); #endif - - +void initDefines(rh3dmpymodule& m); py::dict PointToDict(const ON_3dPoint& point); py::dict VectorToDict(const ON_3dVector& vector); diff --git a/src/bindings/bnd_dimensionstyle.cpp b/src/bindings/bnd_dimensionstyle.cpp index de25b42d..8590edd2 100644 --- a/src/bindings/bnd_dimensionstyle.cpp +++ b/src/bindings/bnd_dimensionstyle.cpp @@ -45,12 +45,8 @@ ON_Arrowhead::arrow_type BND_DimensionStyle::LeaderArrowType() const #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initDimensionStyleBindings(py::module_& m){} -#else -namespace py = pybind11; -void initDimensionStyleBindings(py::module& m) + +void initDimensionStyleBindings(rh3dmpymodule& m) { py::class_ pyDimStyle(m, "DimensionStyle"); @@ -211,7 +207,7 @@ void initDimensionStyleBindings(py::module& m) .value("AlternateDimensionLengthDisplay", ON_DimStyle::field::AlternateDimensionLengthDisplay) ; } -#endif + #endif diff --git a/src/bindings/bnd_dimensionstyle.h b/src/bindings/bnd_dimensionstyle.h index dbfc7382..604e2fe6 100644 --- a/src/bindings/bnd_dimensionstyle.h +++ b/src/bindings/bnd_dimensionstyle.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initDimensionStyleBindings(py::module_& m); -#else -namespace py = pybind11; -void initDimensionStyleBindings(py::module& m); -#endif - +void initDimensionStyleBindings(rh3dmpymodule& m); #else void initDimensionStyleBindings(void* m); #endif diff --git a/src/bindings/bnd_dithering.cpp b/src/bindings/bnd_dithering.cpp index cc8465c7..02a6e532 100644 --- a/src/bindings/bnd_dithering.cpp +++ b/src/bindings/bnd_dithering.cpp @@ -33,12 +33,8 @@ BND_File3dmDithering::BND_File3dmDithering(ON_Dithering* dit) } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initDitheringBindings(py::module_& m){} -#else -namespace py = pybind11; -void initDitheringBindings(py::module& m) + +void initDitheringBindings(rh3dmpymodule& m) { py::class_(m, "Dithering") .def(py::init<>()) @@ -47,7 +43,7 @@ void initDitheringBindings(py::module& m) .def_property("Method", &BND_File3dmDithering::GetMethod, &BND_File3dmDithering::SetMethod) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_dithering.h b/src/bindings/bnd_dithering.h index bfda2836..87b8fa80 100644 --- a/src/bindings/bnd_dithering.h +++ b/src/bindings/bnd_dithering.h @@ -4,14 +4,7 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initDitheringBindings(py::module_& m); -#else -namespace py = pybind11; -void initDitheringBindings(py::module& m); -#endif - +void initDitheringBindings(rh3dmpymodule& m); #else void initDitheringBindings(void* m); #endif diff --git a/src/bindings/bnd_draco.cpp b/src/bindings/bnd_draco.cpp index 4bb61e62..2dd87d34 100644 --- a/src/bindings/bnd_draco.cpp +++ b/src/bindings/bnd_draco.cpp @@ -401,12 +401,8 @@ std::string BND_Draco::ToBase64String() const #endif #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initDracoBindings(py::module_& m){} -#else -namespace py = pybind11; -void initDracoBindings(py::module& m) + +void initDracoBindings(rh3dmpymodule& m) { #if defined(ON_INCLUDE_DRACO) py::class_(m, "DracoCompressionOptions") @@ -424,16 +420,18 @@ void initDracoBindings(py::module& m) .def_static("Compress", &BND_Draco::CompressMesh, py::arg("mesh")) .def_static("Compress", &BND_Draco::CompressMesh2, py::arg("mesh"), py::arg("options")) .def("Write", &BND_Draco::WriteToFile) +#if !defined(NANOBIND) .def_static("DecompressByteArray", [](py::buffer b) { py::buffer_info info = b.request(); return BND_Draco::DecompressByteArray(static_cast(info.size), (const char*)info.ptr); }) +#endif .def_static("DecompressBase64String", &BND_Draco::DecompressBase64, py::arg("encoded")) .def("ToBase64String", &BND_Draco::ToBase64String) ; #endif } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_draco.h b/src/bindings/bnd_draco.h index 6acc5e0e..56eb3bbd 100644 --- a/src/bindings/bnd_draco.h +++ b/src/bindings/bnd_draco.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initDracoBindings(py::module_& m); -#else -namespace py = pybind11; -void initDracoBindings(py::module& m); -#endif - +void initDracoBindings(rh3dmpymodule& m); #else void initDracoBindings(void* m); #endif diff --git a/src/bindings/bnd_ellipse.cpp b/src/bindings/bnd_ellipse.cpp index e498a94c..42af8e4a 100644 --- a/src/bindings/bnd_ellipse.cpp +++ b/src/bindings/bnd_ellipse.cpp @@ -2,17 +2,13 @@ #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initEllipseBindings(py::module_& m){} -#else -namespace py = pybind11; -void initEllipseBindings(py::module& m) + +void initEllipseBindings(rh3dmpymodule& m) { py::class_(m, "Ellipse") ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_ellipse.h b/src/bindings/bnd_ellipse.h index d605806e..95c36bfa 100644 --- a/src/bindings/bnd_ellipse.h +++ b/src/bindings/bnd_ellipse.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initEllipseBindings(py::module_& m); -#else -namespace py = pybind11; -void initEllipseBindings(py::module& m); -#endif - +void initEllipseBindings(rh3dmpymodule& m); #else void initEllipseBindings(void* m); #endif diff --git a/src/bindings/bnd_embedded_file.cpp b/src/bindings/bnd_embedded_file.cpp index fa0d24b5..16432a38 100644 --- a/src/bindings/bnd_embedded_file.cpp +++ b/src/bindings/bnd_embedded_file.cpp @@ -111,12 +111,8 @@ BND_File3dmEmbeddedFile* BND_File3dmEmbeddedFileTable::FindId(BND_UUID id) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initEmbeddedFileBindings(py::module_& m){} -#else -namespace py = pybind11; -void initEmbeddedFileBindings(py::module& m) + +void initEmbeddedFileBindings(rh3dmpymodule& m) { py::class_(m, "EmbeddedFile") .def(py::init<>()) @@ -128,7 +124,7 @@ void initEmbeddedFileBindings(py::module& m) .def("Clear", &BND_File3dmEmbeddedFile::Clear) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_embedded_file.h b/src/bindings/bnd_embedded_file.h index 7c50b603..f360b98d 100644 --- a/src/bindings/bnd_embedded_file.h +++ b/src/bindings/bnd_embedded_file.h @@ -4,14 +4,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initEmbeddedFileBindings(py::module_& m); -#else -namespace py = pybind11; -void initEmbeddedFileBindings(py::module& m); -#endif - +void initEmbeddedFileBindings(rh3dmpymodule& m); #else void initEmbeddedFileBindings(void* m); #endif diff --git a/src/bindings/bnd_extensions.h b/src/bindings/bnd_extensions.h index 0ea7ae22..f672df68 100644 --- a/src/bindings/bnd_extensions.h +++ b/src/bindings/bnd_extensions.h @@ -4,14 +4,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initExtensionsBindings(py::module_& m); -#else -namespace py = pybind11; -void initExtensionsBindings(py::module& m); -#endif - +void initExtensionsBindings(rh3dmpymodule& m); #else void initExtensionsBindings(void* m); #endif diff --git a/src/bindings/bnd_file_utilities.h b/src/bindings/bnd_file_utilities.h index 4aed0879..dd6fbe78 100644 --- a/src/bindings/bnd_file_utilities.h +++ b/src/bindings/bnd_file_utilities.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initFileUtilitiesBindings(py::module_& m); -#else -namespace py = pybind11; -void initFileUtilitiesBindings(py::module& m); -#endif - +void initFileUtilitiesBindings(rh3dmpymodule& m); #else void initFileUtilitiesBindings(void* m); #endif diff --git a/src/bindings/bnd_font.cpp b/src/bindings/bnd_font.cpp index ba20850e..28037c5d 100644 --- a/src/bindings/bnd_font.cpp +++ b/src/bindings/bnd_font.cpp @@ -21,12 +21,8 @@ BND_Font::BND_Font(std::wstring familyName) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initFontBindings(py::module_& m){} -#else -namespace py = pybind11; -void initFontBindings(py::module& m) + +void initFontBindings(rh3dmpymodule& m) { py::class_(m, "Font") .def(py::init(), py::arg("familyName")) @@ -46,7 +42,7 @@ void initFontBindings(py::module& m) .def_property_readonly("FamilyName", &BND_Font::FamilyName) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_font.h b/src/bindings/bnd_font.h index 527c21e1..eab1525f 100644 --- a/src/bindings/bnd_font.h +++ b/src/bindings/bnd_font.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initFontBindings(py::module_& m); -#else -namespace py = pybind11; -void initFontBindings(py::module& m); -#endif - +void initFontBindings(rh3dmpymodule& m); #else void initFontBindings(void* m); #endif diff --git a/src/bindings/bnd_geometry.cpp b/src/bindings/bnd_geometry.cpp index 1c27a13d..89270371 100644 --- a/src/bindings/bnd_geometry.cpp +++ b/src/bindings/bnd_geometry.cpp @@ -33,12 +33,8 @@ bool BND_GeometryBase::Rotate(double rotation_angle, const ON_3dVector& rotation #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initGeometryBindings(py::module_& m){} -#else -namespace py = pybind11; -void initGeometryBindings(py::module& m) + +void initGeometryBindings(rh3dmpymodule& m) { py::class_(m, "GeometryBase") .def_property_readonly("ObjectType", &BND_GeometryBase::ObjectType) @@ -53,7 +49,7 @@ void initGeometryBindings(py::module& m) .def("Duplicate", &BND_GeometryBase::Duplicate) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_geometry.h b/src/bindings/bnd_geometry.h index 74da2888..6d7ce104 100644 --- a/src/bindings/bnd_geometry.h +++ b/src/bindings/bnd_geometry.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initGeometryBindings(py::module_& m); -#else -namespace py = pybind11; -void initGeometryBindings(py::module& m); -#endif - +void initGeometryBindings(rh3dmpymodule& m); #else void initGeometryBindings(void* m); #endif diff --git a/src/bindings/bnd_ground_plane.cpp b/src/bindings/bnd_ground_plane.cpp index a8ad6421..b5a1e4d5 100644 --- a/src/bindings/bnd_ground_plane.cpp +++ b/src/bindings/bnd_ground_plane.cpp @@ -42,12 +42,8 @@ BND_File3dmGroundPlane::BND_File3dmGroundPlane(ON_GroundPlane* gp) } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initGroundPlaneBindings(py::module_& m){} -#else -namespace py = pybind11; -void initGroundPlaneBindings(py::module& m) + +void initGroundPlaneBindings(rh3dmpymodule& m) { py::class_(m, "GroundPlane") .def(py::init<>()) @@ -65,7 +61,7 @@ void initGroundPlaneBindings(py::module& m) .def_property("TextureRotation", &BND_File3dmGroundPlane::GetTextureRotation, &BND_File3dmGroundPlane::SetTextureRotation) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_ground_plane.h b/src/bindings/bnd_ground_plane.h index d603cadc..36e5c422 100644 --- a/src/bindings/bnd_ground_plane.h +++ b/src/bindings/bnd_ground_plane.h @@ -4,14 +4,7 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initGroundPlaneBindings(py::module_& m); -#else -namespace py = pybind11; -void initGroundPlaneBindings(py::module& m); -#endif - +void initGroundPlaneBindings(rh3dmpymodule& m); #else void initGroundPlaneBindings(void* m); #endif diff --git a/src/bindings/bnd_group.cpp b/src/bindings/bnd_group.cpp index dc39b0f7..b5e0f960 100644 --- a/src/bindings/bnd_group.cpp +++ b/src/bindings/bnd_group.cpp @@ -20,12 +20,8 @@ void BND_Group::SetTrackedPointer(ON_Group* group, const ON_ModelComponentRefere #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initGroupBindings(py::module_& m){} -#else -namespace py = pybind11; -void initGroupBindings(py::module& m) + +void initGroupBindings(rh3dmpymodule& m) { py::class_(m, "Group") .def(py::init<>()) @@ -34,7 +30,7 @@ void initGroupBindings(py::module& m) .def_property_readonly("Index", &BND_Group::GetIndex) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_group.h b/src/bindings/bnd_group.h index 2edae193..d60fa023 100644 --- a/src/bindings/bnd_group.h +++ b/src/bindings/bnd_group.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initGroupBindings(py::module_& m); -#else -namespace py = pybind11; -void initGroupBindings(py::module& m); -#endif - +void initGroupBindings(rh3dmpymodule& m); #else void initGroupBindings(void* m); #endif diff --git a/src/bindings/bnd_hatch.cpp b/src/bindings/bnd_hatch.cpp index 146fcbdd..0b0b6aa3 100644 --- a/src/bindings/bnd_hatch.cpp +++ b/src/bindings/bnd_hatch.cpp @@ -19,12 +19,8 @@ void BND_Hatch::SetTrackedPointer(ON_Hatch* hatch, const ON_ModelComponentRefere ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initHatchBindings(py::module_& m){} -#else -namespace py = pybind11; -void initHatchBindings(py::module& m) + +void initHatchBindings(rh3dmpymodule& m) { py::class_(m, "Hatch") .def(py::init<>()) @@ -36,7 +32,7 @@ void initHatchBindings(py::module& m) .def("ScalePattern", &BND_Hatch::ScalePattern, py::arg("xform")) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_hatch.h b/src/bindings/bnd_hatch.h index 934588c1..033cda0b 100644 --- a/src/bindings/bnd_hatch.h +++ b/src/bindings/bnd_hatch.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initHatchBindings(py::module_& m); -#else -namespace py = pybind11; -void initHatchBindings(py::module& m); -#endif - +void initHatchBindings(rh3dmpymodule& m); #else void initHatchBindings(void* m); #endif diff --git a/src/bindings/bnd_instance.cpp b/src/bindings/bnd_instance.cpp index f0455894..e3cdac88 100644 --- a/src/bindings/bnd_instance.cpp +++ b/src/bindings/bnd_instance.cpp @@ -76,12 +76,8 @@ BND_Transform BND_InstanceReferenceGeometry::Xform() const ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initInstanceBindings(py::module_& m){} -#else -namespace py = pybind11; -void initInstanceBindings(py::module& m) + +void initInstanceBindings(rh3dmpymodule& m) { py::enum_(m, "InstanceDefinitionUpdateType") .value("Static", InstanceDefinitionUpdateType::Static) @@ -107,7 +103,7 @@ void initInstanceBindings(py::module& m) .def_property_readonly("Xform", &BND_InstanceReferenceGeometry::Xform) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_instance.h b/src/bindings/bnd_instance.h index 95330290..de4b0365 100644 --- a/src/bindings/bnd_instance.h +++ b/src/bindings/bnd_instance.h @@ -11,14 +11,7 @@ enum class InstanceDefinitionUpdateType : int }; #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initInstanceBindings(py::module_& m); -#else -namespace py = pybind11; -void initInstanceBindings(py::module& m); -#endif - +void initInstanceBindings(rh3dmpymodule& m); #else void initInstanceBindings(void* m); #endif diff --git a/src/bindings/bnd_intersect.h b/src/bindings/bnd_intersect.h index 2473ed1a..37eb5966 100644 --- a/src/bindings/bnd_intersect.h +++ b/src/bindings/bnd_intersect.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initIntersectBindings(py::module_& m); -#else -namespace py = pybind11; -void initIntersectBindings(py::module& m); -#endif - +void initIntersectBindings(rh3dmpymodule& m); #else void initIntersectBindings(void* m); #endif diff --git a/src/bindings/bnd_layer.cpp b/src/bindings/bnd_layer.cpp index 869f45b6..3a2a6f1d 100644 --- a/src/bindings/bnd_layer.cpp +++ b/src/bindings/bnd_layer.cpp @@ -100,12 +100,8 @@ void BND_Layer::SetPlotColor(const BND_Color& color) #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initLayerBindings(py::module_& m){} -#else -namespace py = pybind11; -void initLayerBindings(py::module& m) + +void initLayerBindings(rh3dmpymodule& m) { py::class_(m, "Layer") .def(py::init<>()) @@ -137,7 +133,7 @@ void initLayerBindings(py::module& m) .def_property("Expanded", &BND_Layer::IsExpanded, &BND_Layer::SetExpanded) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_layer.h b/src/bindings/bnd_layer.h index df363084..2235222f 100644 --- a/src/bindings/bnd_layer.h +++ b/src/bindings/bnd_layer.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initLayerBindings(py::module_& m); -#else -namespace py = pybind11; -void initLayerBindings(py::module& m); -#endif - +void initLayerBindings(rh3dmpymodule& m); #else void initLayerBindings(void* m); #endif diff --git a/src/bindings/bnd_light.cpp b/src/bindings/bnd_light.cpp index 77f6cdaf..55917972 100644 --- a/src/bindings/bnd_light.cpp +++ b/src/bindings/bnd_light.cpp @@ -32,12 +32,8 @@ BND_TUPLE BND_Light::GetSpotLightRadii() const #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initLightBindings(py::module_& m){} -#else -namespace py = pybind11; -void initLightBindings(py::module& m) + +void initLightBindings(rh3dmpymodule& m) { py::class_(m, "Light") .def(py::init<>()) @@ -71,7 +67,7 @@ void initLightBindings(py::module& m) .def_property("Name", &BND_Light::GetName, &BND_Light::SetName) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_light.h b/src/bindings/bnd_light.h index 3e01f683..e0366109 100644 --- a/src/bindings/bnd_light.h +++ b/src/bindings/bnd_light.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initLightBindings(py::module_& m); -#else -namespace py = pybind11; -void initLightBindings(py::module& m); -#endif - +void initLightBindings(rh3dmpymodule& m); #else void initLightBindings(void* m); #endif diff --git a/src/bindings/bnd_linear_workflow.cpp b/src/bindings/bnd_linear_workflow.cpp index 19f21c52..6f680d48 100644 --- a/src/bindings/bnd_linear_workflow.cpp +++ b/src/bindings/bnd_linear_workflow.cpp @@ -32,12 +32,8 @@ BND_File3dmLinearWorkflow::BND_File3dmLinearWorkflow(ON_LinearWorkflow* lw) } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initLinearWorkflowBindings(py::module_& m){} -#else -namespace py = pybind11; -void initLinearWorkflowBindings(py::module& m) + +void initLinearWorkflowBindings(rh3dmpymodule& m) { py::class_(m, "LinearWorkflow") .def(py::init<>()) @@ -50,7 +46,7 @@ void initLinearWorkflowBindings(py::module& m) .def_property("PostProcessGammaOn", &BND_File3dmLinearWorkflow::GetPostProcessGammaOn, &BND_File3dmLinearWorkflow::SetPostProcessGammaOn) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_linear_workflow.h b/src/bindings/bnd_linear_workflow.h index 8a021fcd..58352bf5 100644 --- a/src/bindings/bnd_linear_workflow.h +++ b/src/bindings/bnd_linear_workflow.h @@ -4,14 +4,7 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initLinearWorkflowBindings(py::module_& m); -#else -namespace py = pybind11; -void initLinearWorkflowBindings(py::module& m); -#endif - +void initLinearWorkflowBindings(rh3dmpymodule& m); #else void initLinearWorkflowBindings(void* m); #endif diff --git a/src/bindings/bnd_linecurve.cpp b/src/bindings/bnd_linecurve.cpp index 1f411b83..7252ec88 100644 --- a/src/bindings/bnd_linecurve.cpp +++ b/src/bindings/bnd_linecurve.cpp @@ -24,19 +24,15 @@ void BND_LineCurve::SetTrackedPointer(ON_LineCurve* linecurve, const ON_ModelCom #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initLineCurveBindings(py::module_& m){} -#else -namespace py = pybind11; -void initLineCurveBindings(py::module& m) + +void initLineCurveBindings(rh3dmpymodule& m) { py::class_(m, "LineCurve") .def(py::init(), py::arg("start"), py::arg("end")) .def_property("Line", &BND_LineCurve::GetLine, &BND_LineCurve::SetLine) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_linecurve.h b/src/bindings/bnd_linecurve.h index d1d93ac0..1c920d5f 100644 --- a/src/bindings/bnd_linecurve.h +++ b/src/bindings/bnd_linecurve.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initLineCurveBindings(py::module_& m); -#else -namespace py = pybind11; -void initLineCurveBindings(py::module& m); -#endif - +void initLineCurveBindings(rh3dmpymodule& m); #else void initLineCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_linetype.cpp b/src/bindings/bnd_linetype.cpp index 5539bf5c..d562c6be 100644 --- a/src/bindings/bnd_linetype.cpp +++ b/src/bindings/bnd_linetype.cpp @@ -52,12 +52,8 @@ int BND_Linetype::AppendSegment(double length, bool isSolid) #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initLinetypeBindings(py::module_& m){} -#else -namespace py = pybind11; -void initLinetypeBindings(py::module& m) + +void initLinetypeBindings(rh3dmpymodule& m) { py::class_(m, "Linetype") .def(py::init<>()) @@ -81,7 +77,7 @@ void initLinetypeBindings(py::module& m) .def_property_readonly_static("Hidden", &BND_Linetype::Hidden) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_linetype.h b/src/bindings/bnd_linetype.h index 20710ac3..c4653b55 100644 --- a/src/bindings/bnd_linetype.h +++ b/src/bindings/bnd_linetype.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initLinetypeBindings(py::module_& m); -#else -namespace py = pybind11; -void initLinetypeBindings(py::module& m); -#endif - +void initLinetypeBindings(rh3dmpymodule& m); #else void initLinetypeBindings(void* m); #endif diff --git a/src/bindings/bnd_material.cpp b/src/bindings/bnd_material.cpp index 328a30a7..d11fbd0d 100644 --- a/src/bindings/bnd_material.cpp +++ b/src/bindings/bnd_material.cpp @@ -133,12 +133,8 @@ bool BND_PhysicallyBasedMaterial::Supported() const ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initMaterialBindings(py::module_& m){} -#else -namespace py = pybind11; -void initMaterialBindings(py::module& m) + +void initMaterialBindings(rh3dmpymodule& m) { py::class_(m, "PhysicallyBasedMaterial") .def_property_readonly("Supported", &BND_PhysicallyBasedMaterial::Supported) @@ -204,7 +200,7 @@ void initMaterialBindings(py::module& m) .def("ToPhysicallyBased", &BND_Material::ToPhysicallyBased) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_material.h b/src/bindings/bnd_material.h index fb75d771..739d9f9f 100644 --- a/src/bindings/bnd_material.h +++ b/src/bindings/bnd_material.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initMaterialBindings(py::module_& m); -#else -namespace py = pybind11; -void initMaterialBindings(py::module& m); -#endif - +void initMaterialBindings(rh3dmpymodule& m); #else void initMaterialBindings(void* m); #endif diff --git a/src/bindings/bnd_mesh.cpp b/src/bindings/bnd_mesh.cpp index 78711ed4..5b4075da 100644 --- a/src/bindings/bnd_mesh.cpp +++ b/src/bindings/bnd_mesh.cpp @@ -956,12 +956,8 @@ void BND_Mesh::SetCachedTextureCoordinates(class BND_TextureMapping* tm, class B #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initMeshBindings(py::module_& m){} -#else -namespace py = pybind11; -void initMeshBindings(py::module& m) + +void initMeshBindings(rh3dmpymodule& m) { py::class_(m, "MeshingParameters") .def(py::init<>()) @@ -1103,7 +1099,7 @@ void initMeshBindings(py::module& m) .def_property_readonly("PartitionCount", &BND_Mesh::PartitionCount) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_mesh.h b/src/bindings/bnd_mesh.h index ad392182..574b4ccd 100644 --- a/src/bindings/bnd_mesh.h +++ b/src/bindings/bnd_mesh.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initMeshBindings(py::module_& m); -#else -namespace py = pybind11; -void initMeshBindings(py::module& m); -#endif - +void initMeshBindings(rh3dmpymodule& m); #else void initMeshBindings(void* m); #endif diff --git a/src/bindings/bnd_mesh_modifiers.cpp b/src/bindings/bnd_mesh_modifiers.cpp index 365e0d3a..8ce424da 100644 --- a/src/bindings/bnd_mesh_modifiers.cpp +++ b/src/bindings/bnd_mesh_modifiers.cpp @@ -188,12 +188,8 @@ BND_File3dmMeshModifiers::BND_File3dmMeshModifiers(const BND_File3dmMeshModifier ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initMeshModifierBindings(py::module_& m){} -#else -namespace py = pybind11; -void initMeshModifierBindings(py::module& m) + +void initMeshModifierBindings(rh3dmpymodule& m) { py::class_(m, "Displacement") .def(py::init<>()) @@ -269,7 +265,7 @@ void initMeshModifierBindings(py::module& m) .def("DeleteAllCurves", &BND_File3dmShutLining::DeleteAllCurves) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_mesh_modifiers.h b/src/bindings/bnd_mesh_modifiers.h index a9ebaa6d..42b93264 100644 --- a/src/bindings/bnd_mesh_modifiers.h +++ b/src/bindings/bnd_mesh_modifiers.h @@ -4,14 +4,7 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initMeshModifierBindings(py::module_& m); -#else -namespace py = pybind11; -void initMeshModifierBindings(py::module& m); -#endif - +void initMeshModifierBindings(rh3dmpymodule& m); #else void initMeshModifierBindings(void* m); #endif diff --git a/src/bindings/bnd_model_component.cpp b/src/bindings/bnd_model_component.cpp index 4318f078..af94b8cd 100644 --- a/src/bindings/bnd_model_component.cpp +++ b/src/bindings/bnd_model_component.cpp @@ -22,12 +22,8 @@ void BND_ModelComponent::SetId(BND_UUID id) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initModelComponentBindings(py::module_& m){} -#else -namespace py = pybind11; -void initModelComponentBindings(py::module& m) + +void initModelComponentBindings(rh3dmpymodule& m) { py::class_(m, "ModelComponent") .def("DataCRC", &BND_ModelComponent::DataCRC, py::arg("currentRemainder")) @@ -36,7 +32,7 @@ void initModelComponentBindings(py::module& m) .def("ClearId", &BND_ModelComponent::ClearId) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_model_component.h b/src/bindings/bnd_model_component.h index e5f36dfd..bf6d327b 100644 --- a/src/bindings/bnd_model_component.h +++ b/src/bindings/bnd_model_component.h @@ -43,14 +43,7 @@ class BND_ModelComponent : public BND_CommonObject #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initModelComponentBindings(py::module_& m); -#else -namespace py = pybind11; -void initModelComponentBindings(py::module& m); -#endif - +void initModelComponentBindings(rh3dmpymodule& m); #else void initModelComponentBindings(void* m); #endif diff --git a/src/bindings/bnd_nurbscurve.cpp b/src/bindings/bnd_nurbscurve.cpp index d6370811..0dfa7d8e 100644 --- a/src/bindings/bnd_nurbscurve.cpp +++ b/src/bindings/bnd_nurbscurve.cpp @@ -222,18 +222,15 @@ BND_BezierCurve* BND_NurbsCurve::ConvertSpanToBezier(int index) const /////////////////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initNurbsCurveBindings(py::module_& m){} -#else -namespace py = pybind11; -void initNurbsCurveBindings(py::module& m) + +void initNurbsCurveBindings(rh3dmpymodule& m) { - py::class_(m, "NurbsCurveKnotList", py::buffer_protocol()) + py::class_(m, "NurbsCurveKnotList" /* , py::buffer_protocol()*/) .def("__len__", &BND_NurbsCurveKnotList::Count) .def("__getitem__", &BND_NurbsCurveKnotList::GetKnot) .def("__setitem__", &BND_NurbsCurveKnotList::SetKnot) .def("ToList", &BND_NurbsCurveKnotList::ToList) +#if !defined(NANOBIND) .def_buffer([](BND_NurbsCurveKnotList& kl) -> py::buffer_info { return py::buffer_info @@ -246,6 +243,7 @@ void initNurbsCurveBindings(py::module& m) {sizeof(double)} /* Strides (in bytes) for each index */ ); }) +#endif .def("InsertKnot", &BND_NurbsCurveKnotList::InsertKnot, py::arg("value"), py::arg("multiplicity")) .def("KnotMultiplicity", &BND_NurbsCurveKnotList::KnotMultiplicity, py::arg("index")) .def("CreateUniformKnots", &BND_NurbsCurveKnotList::CreateUniformKnots, py::arg("knotSpacing")) @@ -256,10 +254,11 @@ void initNurbsCurveBindings(py::module& m) ; ; - py::class_(m, "NurbsCurvePointList", py::buffer_protocol()) + py::class_(m, "NurbsCurvePointList"/*, py::buffer_protocol()*/) .def("__len__", &BND_NurbsCurvePointList::Count) .def("__getitem__", &BND_NurbsCurvePointList::GetControlPoint) .def("__setitem__", &BND_NurbsCurvePointList::SetControlPoint) +#if !defined(NANOBIND) .def_buffer([](BND_NurbsCurvePointList& pl) -> py::buffer_info { return py::buffer_info @@ -272,6 +271,7 @@ void initNurbsCurveBindings(py::module& m) {pl.GetCurve()->m_cv_stride * sizeof(double), sizeof(double)} /* Strides (in bytes) for each index */ ); }) +#endif .def_property_readonly("ControlPolygonLength", &BND_NurbsCurvePointList::ControlPolygonLength) .def("ChangeEndWeights", &BND_NurbsCurvePointList::ChangeEndWeights, py::arg("w0"), py::arg("w1")) .def("MakeRational", &BND_NurbsCurvePointList::MakeRational) @@ -300,7 +300,7 @@ void initNurbsCurveBindings(py::module& m) .def_property_readonly("Knots", &BND_NurbsCurve::Knots) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_nurbscurve.h b/src/bindings/bnd_nurbscurve.h index 6abb4d58..33974c43 100644 --- a/src/bindings/bnd_nurbscurve.h +++ b/src/bindings/bnd_nurbscurve.h @@ -4,14 +4,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initNurbsCurveBindings(py::module_& m); -#else -namespace py = pybind11; -void initNurbsCurveBindings(py::module& m); -#endif - +void initNurbsCurveBindings(rh3dmpymodule& m); #else void initNurbsCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_nurbssurface.cpp b/src/bindings/bnd_nurbssurface.cpp index 1daba63a..80600ffa 100644 --- a/src/bindings/bnd_nurbssurface.cpp +++ b/src/bindings/bnd_nurbssurface.cpp @@ -197,18 +197,15 @@ BND_NurbsSurfacePointList BND_NurbsSurface::Points() #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initNurbsSurfaceBindings(py::module_& m){} -#else -namespace py = pybind11; -void initNurbsSurfaceBindings(py::module& m) + +void initNurbsSurfaceBindings(rh3dmpymodule& m) { - py::class_(m, "NurbsSurfaceKnotList", py::buffer_protocol()) + py::class_(m, "NurbsSurfaceKnotList" /* , py::buffer_protocol() */) .def("__len__", &BND_NurbsSurfaceKnotList::Count) .def("__getitem__", &BND_NurbsSurfaceKnotList::GetKnot) .def("__setitem__", &BND_NurbsSurfaceKnotList::SetKnot) .def("ToList", &BND_NurbsSurfaceKnotList::ToList) +#if !defined(NANOBIND) .def_buffer([](BND_NurbsSurfaceKnotList& kl) -> py::buffer_info { return py::buffer_info @@ -221,6 +218,7 @@ void initNurbsSurfaceBindings(py::module& m) {sizeof(double)} /* Strides (in bytes) for each index */ ); }) +#endif .def("InsertKnot", &BND_NurbsSurfaceKnotList::InsertKnot, py::arg("value"), py::arg("multiplicity")) .def("KnotMultiplicity", &BND_NurbsSurfaceKnotList::KnotMultiplicity, py::arg("index")) .def("CreateUniformKnots", &BND_NurbsSurfaceKnotList::CreateUniformKnots, py::arg("knotSpacing")) @@ -230,7 +228,7 @@ void initNurbsSurfaceBindings(py::module& m) .def("SuperfluousKnot", &BND_NurbsSurfaceKnotList::SuperfluousKnot, py::arg("start")) ; - py::class_(m, "NurbsSurfacePointList", py::buffer_protocol()) + py::class_(m, "NurbsSurfacePointList"/* , py::buffer_protocol() */) .def("__len__", &BND_NurbsSurfacePointList::Count) .def_property_readonly("CountU", &BND_NurbsSurfacePointList::CountU) .def_property_readonly("CountV", &BND_NurbsSurfacePointList::CountV) @@ -238,6 +236,7 @@ void initNurbsSurfaceBindings(py::module& m) .def("GetPoint", &BND_NurbsSurfacePointList::GetPoint, py::arg("u"), py::arg("v") ) .def("GetControlPoint", &BND_NurbsSurfacePointList::GetControlPoint2, py::arg("u"), py::arg("v") ) .def("__setitem__", &BND_NurbsSurfacePointList::SetControlPoint1) +#if !defined(NANOBIND) .def_buffer([](BND_NurbsSurfacePointList& pl) -> py::buffer_info { return py::buffer_info @@ -254,6 +253,7 @@ void initNurbsSurfaceBindings(py::module& m) } /* Strides (in bytes) for each index */ ); }) +#endif .def("MakeRational", &BND_NurbsSurfacePointList::MakeRational) .def("MakeNonRational", &BND_NurbsSurfacePointList::MakeNonRational) ; @@ -275,7 +275,7 @@ void initNurbsSurfaceBindings(py::module& m) .def_property_readonly("Points", &BND_NurbsSurface::Points) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_nurbssurface.h b/src/bindings/bnd_nurbssurface.h index da66d3e0..731455d1 100644 --- a/src/bindings/bnd_nurbssurface.h +++ b/src/bindings/bnd_nurbssurface.h @@ -4,14 +4,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initNurbsSurfaceBindings(py::module_& m); -#else -namespace py = pybind11; -void initNurbsSurfaceBindings(py::module& m); -#endif - +void initNurbsSurfaceBindings(rh3dmpymodule& m); #else void initNurbsSurfaceBindings(void* m); #endif diff --git a/src/bindings/bnd_object.cpp b/src/bindings/bnd_object.cpp index 6de55bea..e6f3ff7b 100644 --- a/src/bindings/bnd_object.cpp +++ b/src/bindings/bnd_object.cpp @@ -930,12 +930,12 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) const unsigned char* c = (const unsigned char*)&decoded.at(0); // Eliminate potential bogus file versions written #if defined(ON_PYTHON_COMPILE) - py::cast_error exception();//("Unable to decode ArchivableDictionary"); + //py::cast_error exception();//("Unable to decode ArchivableDictionary"); if (rhinoversion > 5 && rhinoversion < 50) - throw exception; + throw py::cast_error(); if (length < 1 || nullptr == c) - throw exception; + throw py::cast_error(); #endif ON_Read3dmBufferArchive archive((size_t)length, c, false, rhinoversion, opennurbsversion); @@ -944,9 +944,9 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) ON_wString dictionaryName; #if defined(ON_PYTHON_COMPILE) if (!archive.BeginReadDictionary(&dictionaryId, &dictionaryVersion, dictionaryName)) - throw exception; + throw py::cast_error(); if (dictionaryId != RhinoDotNetDictionaryId()) - throw exception; + throw py::cast_error(); #else archive.BeginReadDictionary(&dictionaryId, &dictionaryVersion, dictionaryName); #endif @@ -958,7 +958,7 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) int read_rc = archive.BeginReadDictionaryEntry(&i_type, entryName); #if defined(ON_PYTHON_COMPILE) if (0 == read_rc) - throw exception; + throw py::cast_error(); #else if (0 == read_rc) break; @@ -1451,7 +1451,7 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) } #if defined(ON_PYTHON_COMPILE) if (!archive.EndReadDictionaryEntry()) - throw exception; + throw py::cast_error();; #else archive.EndReadDictionaryEntry(); #endif @@ -1547,12 +1547,8 @@ BND_TUPLE BND_CommonObject::IsValidWithLog() const } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initObjectBindings(py::module_& m){} -#else -namespace py = pybind11; -void initObjectBindings(py::module& m) + +void initObjectBindings(rh3dmpymodule& m) { py::class_(m, "CommonObject") .def_property_readonly("IsValid", &BND_CommonObject::IsValid) @@ -1572,7 +1568,7 @@ void initObjectBindings(py::module& m) ////.def_static("WriteGeometry", &BND_ArchivableDictionary::WriteGeometry) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_object.h b/src/bindings/bnd_object.h index a5b2df27..3d4180c1 100644 --- a/src/bindings/bnd_object.h +++ b/src/bindings/bnd_object.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initObjectBindings(py::module_& m); -#else -namespace py = pybind11; -void initObjectBindings(py::module& m); -#endif - +void initObjectBindings(rh3dmpymodule& m); #else void initObjectBindings(void* m); #endif diff --git a/src/bindings/bnd_plane.cpp b/src/bindings/bnd_plane.cpp index 01b1f19f..1440bf46 100644 --- a/src/bindings/bnd_plane.cpp +++ b/src/bindings/bnd_plane.cpp @@ -200,12 +200,8 @@ BND_Plane BND_PlaneHelper::WorldXY() } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPlaneBindings(py::module_& m){} -#else -namespace py = pybind11; -void initPlaneBindings(py::module& m) + +void initPlaneBindings(rh3dmpymodule& m) { py::class_(m, "Plane") .def_static("WorldXY", &BND_Plane::WorldXY) @@ -228,7 +224,7 @@ void initPlaneBindings(py::module& m) .def_static("Decode", &BND_Plane::Decode, py::arg("jsonObject")) ; } -#endif + #endif diff --git a/src/bindings/bnd_plane.h b/src/bindings/bnd_plane.h index 9a2eb35c..7e05415b 100644 --- a/src/bindings/bnd_plane.h +++ b/src/bindings/bnd_plane.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPlaneBindings(py::module_& m); -#else -namespace py = pybind11; -void initPlaneBindings(py::module& m); -#endif - +void initPlaneBindings(rh3dmpymodule& m); #else void initPlaneBindings(void* m); #endif diff --git a/src/bindings/bnd_planesurface.cpp b/src/bindings/bnd_planesurface.cpp index 3d8874ec..82245a36 100644 --- a/src/bindings/bnd_planesurface.cpp +++ b/src/bindings/bnd_planesurface.cpp @@ -30,19 +30,15 @@ BND_PlaneSurface::BND_PlaneSurface(const BND_Plane& plane, const BND_Interval& x ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPlaneSurfaceBindings(py::module_& m){} -#else -namespace py = pybind11; -void initPlaneSurfaceBindings(py::module& m) + +void initPlaneSurfaceBindings(rh3dmpymodule& m) { py::class_(m, "PlaneSurface") .def(py::init<>()) .def(py::init(), py::arg("plane"), py::arg("xExtents"), py::arg("yExtents")) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_planesurface.h b/src/bindings/bnd_planesurface.h index 6aa96d0d..aaf992fa 100644 --- a/src/bindings/bnd_planesurface.h +++ b/src/bindings/bnd_planesurface.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPlaneSurfaceBindings(py::module_& m); -#else -namespace py = pybind11; -void initPlaneSurfaceBindings(py::module& m); -#endif - +void initPlaneSurfaceBindings(rh3dmpymodule& m); #else void initPlaneSurfaceBindings(void* m); #endif diff --git a/src/bindings/bnd_point.cpp b/src/bindings/bnd_point.cpp index da07271a..035c6440 100644 --- a/src/bindings/bnd_point.cpp +++ b/src/bindings/bnd_point.cpp @@ -312,7 +312,7 @@ static std::string ReprInterval(const BND_Interval& i) return repr.str(); } -void initPointBindings(py::module& m) +void initPointBindings(rh3dmpymodule& m) { py::class_(m, "Point2d") .def(py::init(), py::arg("x"), py::arg("y")) diff --git a/src/bindings/bnd_point.h b/src/bindings/bnd_point.h index 342a62e3..26ef232d 100644 --- a/src/bindings/bnd_point.h +++ b/src/bindings/bnd_point.h @@ -6,14 +6,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPointBindings(py::module_& m); -#else -namespace py = pybind11; -void initPointBindings(py::module& m); -#endif - +void initPointBindings(rh3dmpymodule& m); #else void initPointBindings(void* m); #endif diff --git a/src/bindings/bnd_pointcloud.cpp b/src/bindings/bnd_pointcloud.cpp index 28ed24ee..6c84ee77 100644 --- a/src/bindings/bnd_pointcloud.cpp +++ b/src/bindings/bnd_pointcloud.cpp @@ -808,12 +808,8 @@ BND_DICT BND_PointCloud::ToThreejsJSON() const ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPointCloudBindings(py::module_& m){} -#else -namespace py = pybind11; -void initPointCloudBindings(py::module& m) + +void initPointCloudBindings(rh3dmpymodule& m) { py::class_(m, "PointCloudItem") .def_property("Location", &BND_PointCloudItem::GetLocation, &BND_PointCloudItem::SetLocation) @@ -873,7 +869,7 @@ void initPointCloudBindings(py::module& m) .def("ClosestPoint", &BND_PointCloud::ClosestPoint, py::arg("testPoint")) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_pointcloud.h b/src/bindings/bnd_pointcloud.h index 803648e7..45d91e61 100644 --- a/src/bindings/bnd_pointcloud.h +++ b/src/bindings/bnd_pointcloud.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPointCloudBindings(py::module_& m); -#else -namespace py = pybind11; -void initPointCloudBindings(py::module& m); -#endif - +void initPointCloudBindings(rh3dmpymodule& m); #else void initPointCloudBindings(void* m); #endif diff --git a/src/bindings/bnd_pointgeometry.cpp b/src/bindings/bnd_pointgeometry.cpp index c872e85d..8eb93601 100644 --- a/src/bindings/bnd_pointgeometry.cpp +++ b/src/bindings/bnd_pointgeometry.cpp @@ -25,12 +25,8 @@ void BND_Point::SetTrackedPointer(ON_Point* point, const ON_ModelComponentRefere ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPointGeometryBindings(py::module_& m){} -#else -namespace py = pybind11; -void initPointGeometryBindings(py::module& m) + +void initPointGeometryBindings(rh3dmpymodule& m) { py::class_(m, "Point") .def(py::init<>()) @@ -38,7 +34,7 @@ void initPointGeometryBindings(py::module& m) .def_property("Location", &BND_Point::GetLocation, &BND_Point::SetLocation) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_pointgeometry.h b/src/bindings/bnd_pointgeometry.h index 0bcc235c..aa9a8e73 100644 --- a/src/bindings/bnd_pointgeometry.h +++ b/src/bindings/bnd_pointgeometry.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPointGeometryBindings(py::module_& m); -#else -namespace py = pybind11; -void initPointGeometryBindings(py::module& m); -#endif - +void initPointGeometryBindings(rh3dmpymodule& m); #else void initPointGeometryBindings(void* m); #endif diff --git a/src/bindings/bnd_pointgrid.cpp b/src/bindings/bnd_pointgrid.cpp index 3cecfc9c..3c52fc0b 100644 --- a/src/bindings/bnd_pointgrid.cpp +++ b/src/bindings/bnd_pointgrid.cpp @@ -19,18 +19,14 @@ void BND_PointGrid::SetTrackedPointer(ON_PointGrid* pointgrid, const ON_ModelCom ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPointGridBindings(py::module_& m){} -#else -namespace py = pybind11; -void initPointGridBindings(py::module& m) + +void initPointGridBindings(rh3dmpymodule& m) { py::class_(m, "PointGrid") .def(py::init<>()) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_pointgrid.h b/src/bindings/bnd_pointgrid.h index c568830a..7839ce2d 100644 --- a/src/bindings/bnd_pointgrid.h +++ b/src/bindings/bnd_pointgrid.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPointGridBindings(py::module_& m); -#else -namespace py = pybind11; -void initPointGridBindings(py::module& m); -#endif - +void initPointGridBindings(rh3dmpymodule& m); #else void initPointGridBindings(void* m); #endif diff --git a/src/bindings/bnd_polycurve.cpp b/src/bindings/bnd_polycurve.cpp index ca5a7e74..f955d313 100644 --- a/src/bindings/bnd_polycurve.cpp +++ b/src/bindings/bnd_polycurve.cpp @@ -110,12 +110,8 @@ int BND_PolyCurve::SegmentIndex(double polycurveParameter) const ///////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPolyCurveBindings(py::module_& m){} -#else -namespace py = pybind11; -void initPolyCurveBindings(py::module& m) + +void initPolyCurveBindings(rh3dmpymodule& m) { py::class_(m, "PolyCurve") .def(py::init<>()) @@ -135,7 +131,7 @@ void initPolyCurveBindings(py::module& m) .def("SegmentIndex", &BND_PolyCurve::SegmentIndex, py::arg("polycurveParameter")) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_polycurve.h b/src/bindings/bnd_polycurve.h index 0cee8286..4c2c3170 100644 --- a/src/bindings/bnd_polycurve.h +++ b/src/bindings/bnd_polycurve.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPolyCurveBindings(py::module_& m); -#else -namespace py = pybind11; -void initPolyCurveBindings(py::module& m); -#endif - +void initPolyCurveBindings(rh3dmpymodule& m); #else void initPolyCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_polyline.cpp b/src/bindings/bnd_polyline.cpp index 79a0fb44..c1d47c5b 100644 --- a/src/bindings/bnd_polyline.cpp +++ b/src/bindings/bnd_polyline.cpp @@ -192,12 +192,8 @@ void BND_Point3dList::Append2 (const std::vector& points) ////////////////////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPolylineBindings(py::module_& m){} -#else -namespace py = pybind11; -void initPolylineBindings(py::module& m) + +void initPolylineBindings(rh3dmpymodule& m) { py::class_(m, "Point3dList") .def(py::init<>()) @@ -245,7 +241,7 @@ void initPolylineBindings(py::module& m) .def_static("CreateFromPoints", &BND_Polyline::CreateFromPoints2, py::arg("points")) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_polyline.h b/src/bindings/bnd_polyline.h index c8de3a4f..fdd8f8b2 100644 --- a/src/bindings/bnd_polyline.h +++ b/src/bindings/bnd_polyline.h @@ -2,14 +2,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPolylineBindings(py::module_& m); -#else -namespace py = pybind11; -void initPolylineBindings(py::module& m); -#endif - +void initPolylineBindings(rh3dmpymodule& m); #else void initPolylineBindings(void* m); #endif diff --git a/src/bindings/bnd_polylinecurve.cpp b/src/bindings/bnd_polylinecurve.cpp index eff1d12f..0de4f4be 100644 --- a/src/bindings/bnd_polylinecurve.cpp +++ b/src/bindings/bnd_polylinecurve.cpp @@ -62,12 +62,8 @@ BND_Polyline* BND_PolylineCurve::ToPolyline() const ////////////////////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPolylineCurveBindings(py::module_& m){} -#else -namespace py = pybind11; -void initPolylineCurveBindings(py::module& m) + +void initPolylineCurveBindings(rh3dmpymodule& m) { py::class_(m, "PolylineCurve") .def(py::init<>()) @@ -79,7 +75,7 @@ void initPolylineCurveBindings(py::module& m) .def("ToPolyline", &BND_PolylineCurve::ToPolyline) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_polylinecurve.h b/src/bindings/bnd_polylinecurve.h index ebd21ad0..720014f9 100644 --- a/src/bindings/bnd_polylinecurve.h +++ b/src/bindings/bnd_polylinecurve.h @@ -2,14 +2,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPolylineCurveBindings(py::module_& m); -#else -namespace py = pybind11; -void initPolylineCurveBindings(py::module& m); -#endif - +void initPolylineCurveBindings(rh3dmpymodule& m); #else void initPolylineCurveBindings(void* m); #endif diff --git a/src/bindings/bnd_post_effects.cpp b/src/bindings/bnd_post_effects.cpp index 3fbe8bd4..12ae231b 100644 --- a/src/bindings/bnd_post_effects.cpp +++ b/src/bindings/bnd_post_effects.cpp @@ -179,12 +179,8 @@ int BND_File3dmPostEffectTable::Count() const ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPostEffectBindings(py::module_& m){} -#else -namespace py = pybind11; -void initPostEffectBindings(py::module& m) + +void initPostEffectBindings(rh3dmpymodule& m) { py::class_(m, "PostEffect") .def(py::init<>()) @@ -200,7 +196,7 @@ void initPostEffectBindings(py::module& m) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_post_effects.h b/src/bindings/bnd_post_effects.h index 538dda25..7632b3ad 100644 --- a/src/bindings/bnd_post_effects.h +++ b/src/bindings/bnd_post_effects.h @@ -4,14 +4,7 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initPostEffectBindings(py::module_& m); -#else -namespace py = pybind11; -void initPostEffectBindings(py::module& m); -#endif - +void initPostEffectBindings(rh3dmpymodule& m); #else void initPostEffectBindings(void* m); #endif diff --git a/src/bindings/bnd_render_channels.cpp b/src/bindings/bnd_render_channels.cpp index a4e3aaab..df1c438c 100644 --- a/src/bindings/bnd_render_channels.cpp +++ b/src/bindings/bnd_render_channels.cpp @@ -66,12 +66,8 @@ void BND_File3dmRenderChannels::SetCustomList(BND_TUPLE tuple) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initRenderChannelsBindings(py::module_& m){} -#else -namespace py = pybind11; -void initRenderChannelsBindings(py::module& m) + +void initRenderChannelsBindings(rh3dmpymodule& m) { py::class_(m, "RenderChannels") .def(py::init<>()) @@ -80,7 +76,7 @@ void initRenderChannelsBindings(py::module& m) .def_property("CustomIds", &BND_File3dmRenderChannels::GetCustomList, &BND_File3dmRenderChannels::SetCustomList) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_render_channels.h b/src/bindings/bnd_render_channels.h index c2dd6539..86f5cd76 100644 --- a/src/bindings/bnd_render_channels.h +++ b/src/bindings/bnd_render_channels.h @@ -4,14 +4,7 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initRenderChannelsBindings(py::module_& m); -#else -namespace py = pybind11; -void initRenderChannelsBindings(py::module& m); -#endif - +void initRenderChannelsBindings(rh3dmpymodule& m); #else void initRenderChannelsBindings(void* m); #endif diff --git a/src/bindings/bnd_render_content.cpp b/src/bindings/bnd_render_content.cpp index 9ed235a7..105d479b 100644 --- a/src/bindings/bnd_render_content.cpp +++ b/src/bindings/bnd_render_content.cpp @@ -444,12 +444,8 @@ BND_File3dmRenderContent* BND_File3dmRenderContentTable::FindId(BND_UUID id) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initRenderContentBindings(py::module_& m){} -#else -namespace py = pybind11; -void initRenderContentBindings(py::module& m) + +void initRenderContentBindings(rh3dmpymodule& m) { py::class_(m, "RenderContent") .def(py::init<>()) @@ -506,7 +502,7 @@ void initRenderContentBindings(py::module& m) .def_property("FileName", &BND_File3dmRenderTexture::Filename, &BND_File3dmRenderTexture::SetFilename) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_render_content.h b/src/bindings/bnd_render_content.h index bde9a9da..7e9a1622 100644 --- a/src/bindings/bnd_render_content.h +++ b/src/bindings/bnd_render_content.h @@ -4,14 +4,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initRenderContentBindings(py::module_& m); -#else -namespace py = pybind11; -void initRenderContentBindings(py::module& m); -#endif - +void initRenderContentBindings(rh3dmpymodule& m); #else void initRenderContentBindings(void* m); #endif diff --git a/src/bindings/bnd_render_environments.cpp b/src/bindings/bnd_render_environments.cpp index 6af469d2..d3d70f02 100644 --- a/src/bindings/bnd_render_environments.cpp +++ b/src/bindings/bnd_render_environments.cpp @@ -87,12 +87,8 @@ void BND_File3dmRenderEnvironments::SetReflectionId(const BND_UUID& id) ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initRenderEnvironmentsBindings(py::module_& m){} -#else -namespace py = pybind11; -void initRenderEnvironmentsBindings(py::module& m) + +void initRenderEnvironmentsBindings(rh3dmpymodule& m) { py::class_(m, "RenderEnvironments") .def(py::init<>()) @@ -104,7 +100,7 @@ void initRenderEnvironmentsBindings(py::module& m) .def_property("ReflectionOverride", &BND_File3dmRenderEnvironments::GetReflectionOverride, &BND_File3dmRenderEnvironments::SetReflectionOverride) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_render_environments.h b/src/bindings/bnd_render_environments.h index 7d1dc377..20ea2b77 100644 --- a/src/bindings/bnd_render_environments.h +++ b/src/bindings/bnd_render_environments.h @@ -4,14 +4,7 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initRenderEnvironmentsBindings(py::module_& m); -#else -namespace py = pybind11; -void initRenderEnvironmentsBindings(py::module& m); -#endif - +void initRenderEnvironmentsBindings(rh3dmpymodule& m); #else void initRenderEnvironmentsBindings(void* m); #endif diff --git a/src/bindings/bnd_revsurface.cpp b/src/bindings/bnd_revsurface.cpp index b3a00e5e..7ae7b4d3 100644 --- a/src/bindings/bnd_revsurface.cpp +++ b/src/bindings/bnd_revsurface.cpp @@ -37,19 +37,15 @@ BND_RevSurface* BND_RevSurface::Create1(const BND_Curve& revoluteCurve, const ON ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initRevSurfaceBindings(py::module_& m){} -#else -namespace py = pybind11; -void initRevSurfaceBindings(py::module& m) + +void initRevSurfaceBindings(rh3dmpymodule& m) { py::class_(m, "RevSurface") .def(py::init<>()) .def_static("Create", &BND_RevSurface::Create1, py::arg("revoluteCurve"), py::arg("axisOfRevolution"), py::arg("startAngle"), py::arg("endAngle")) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_revsurface.h b/src/bindings/bnd_revsurface.h index eae712eb..e71912fa 100644 --- a/src/bindings/bnd_revsurface.h +++ b/src/bindings/bnd_revsurface.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initRevSurfaceBindings(py::module_& m); -#else -namespace py = pybind11; -void initRevSurfaceBindings(py::module& m); -#endif - +void initRevSurfaceBindings(rh3dmpymodule& m); #else void initRevSurfaceBindings(void* m); #endif diff --git a/src/bindings/bnd_rtree.cpp b/src/bindings/bnd_rtree.cpp index 3d17f64b..7f87f2ce 100644 --- a/src/bindings/bnd_rtree.cpp +++ b/src/bindings/bnd_rtree.cpp @@ -3,18 +3,14 @@ #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initRTreeBindings(py::module_& m){} -#else -namespace py = pybind11; -void initRTreeBindings(py::module& m) + +void initRTreeBindings(rh3dmpymodule& m) { //py::class_(m, "RTree") // .def(py::init<>()) // ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_rtree.h b/src/bindings/bnd_rtree.h index 5428860e..34ee1336 100644 --- a/src/bindings/bnd_rtree.h +++ b/src/bindings/bnd_rtree.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initRTreeBindings(py::module_& m); -#else -namespace py = pybind11; -void initRTreeBindings(py::module& m); -#endif - +void initRTreeBindings(rh3dmpymodule& m); #else void initRTreeBindings(void* m); #endif diff --git a/src/bindings/bnd_safe_frame.cpp b/src/bindings/bnd_safe_frame.cpp index 9a092569..e7a4e68f 100644 --- a/src/bindings/bnd_safe_frame.cpp +++ b/src/bindings/bnd_safe_frame.cpp @@ -32,12 +32,8 @@ BND_File3dmSafeFrame::BND_File3dmSafeFrame(ON_SafeFrame* sf) } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSafeFrameBindings(py::module_& m){} -#else -namespace py = pybind11; -void initSafeFrameBindings(py::module& m) + +void initSafeFrameBindings(rh3dmpymodule& m) { py::class_(m, "SafeFrame") .def(py::init<>()) @@ -56,7 +52,7 @@ void initSafeFrameBindings(py::module& m) .def_property("TitleFrameYScale", &BND_File3dmSafeFrame::GetTitleFrameYScale, &BND_File3dmSafeFrame::SetTitleFrameYScale) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_safe_frame.h b/src/bindings/bnd_safe_frame.h index 235798fc..50c06059 100644 --- a/src/bindings/bnd_safe_frame.h +++ b/src/bindings/bnd_safe_frame.h @@ -4,14 +4,7 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSafeFrameBindings(py::module_& m); -#else -namespace py = pybind11; -void initSafeFrameBindings(py::module& m); -#endif - +void initSafeFrameBindings(rh3dmpymodule& m); #else void initSafeFrameBindings(void* m); #endif diff --git a/src/bindings/bnd_skylight.cpp b/src/bindings/bnd_skylight.cpp index d47a9920..748ec6f7 100644 --- a/src/bindings/bnd_skylight.cpp +++ b/src/bindings/bnd_skylight.cpp @@ -32,12 +32,8 @@ BND_File3dmSkylight::BND_File3dmSkylight(ON_Skylight* sl) } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSkylightBindings(py::module_& m){} -#else -namespace py = pybind11; -void initSkylightBindings(py::module& m) + +void initSkylightBindings(rh3dmpymodule& m) { py::class_(m, "Skylight") .def(py::init<>()) @@ -46,7 +42,7 @@ void initSkylightBindings(py::module& m) .def_property("ShadowIntensity", &BND_File3dmSkylight::GetShadowIntensity, &BND_File3dmSkylight::SetShadowIntensity) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_skylight.h b/src/bindings/bnd_skylight.h index 8db42fb5..fb4ef0b8 100644 --- a/src/bindings/bnd_skylight.h +++ b/src/bindings/bnd_skylight.h @@ -4,14 +4,7 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSkylightBindings(py::module_& m); -#else -namespace py = pybind11; -void initSkylightBindings(py::module& m); -#endif - +void initSkylightBindings(rh3dmpymodule& m); #else void initSkylightBindings(void* m); #endif diff --git a/src/bindings/bnd_sphere.cpp b/src/bindings/bnd_sphere.cpp index 9ad01452..da6a9837 100644 --- a/src/bindings/bnd_sphere.cpp +++ b/src/bindings/bnd_sphere.cpp @@ -119,12 +119,8 @@ BND_Sphere* BND_Sphere::Decode(emscripten::val jsonObject) #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSphereBindings(py::module_& m){} -#else -namespace py = pybind11; -void initSphereBindings(py::module& m) + +void initSphereBindings(rh3dmpymodule& m) { py::class_(m, "Sphere") .def(py::init(), py::arg("center"), py::arg("radius")) @@ -148,7 +144,7 @@ void initSphereBindings(py::module& m) .def_static("Decode", &BND_Sphere::Decode, py::arg("jsonObject")) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_sphere.h b/src/bindings/bnd_sphere.h index 02b37d5b..003f8d4b 100644 --- a/src/bindings/bnd_sphere.h +++ b/src/bindings/bnd_sphere.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSphereBindings(py::module_& m); -#else -namespace py = pybind11; -void initSphereBindings(py::module& m); -#endif - +void initSphereBindings(rh3dmpymodule& m); #else void initSphereBindings(void* m); #endif diff --git a/src/bindings/bnd_subd.cpp b/src/bindings/bnd_subd.cpp index 1d9569ab..01941402 100644 --- a/src/bindings/bnd_subd.cpp +++ b/src/bindings/bnd_subd.cpp @@ -18,12 +18,8 @@ BND_SubD::BND_SubD() #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSubDBindings(py::module_& m){} -#else -namespace py = pybind11; -void initSubDBindings(py::module& m) + +void initSubDBindings(rh3dmpymodule& m) { py::class_(m, "SubD") .def(py::init<>()) @@ -33,7 +29,7 @@ void initSubDBindings(py::module& m) .def("Subdivide", &BND_SubD::Subdivide, py::arg("count")) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_subd.h b/src/bindings/bnd_subd.h index f84f5afd..4f3166a1 100644 --- a/src/bindings/bnd_subd.h +++ b/src/bindings/bnd_subd.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSubDBindings(py::module_& m); -#else -namespace py = pybind11; -void initSubDBindings(py::module& m); -#endif - +void initSubDBindings(rh3dmpymodule& m); #else void initSubDBindings(void* m); #endif diff --git a/src/bindings/bnd_sun.cpp b/src/bindings/bnd_sun.cpp index c072abbd..ef29ab28 100644 --- a/src/bindings/bnd_sun.cpp +++ b/src/bindings/bnd_sun.cpp @@ -108,12 +108,8 @@ BND_Color BND_File3dmSun::GetSunColorFromAltitude(double v) // Static. ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSunBindings(py::module_& m){} -#else -namespace py = pybind11; -void initSunBindings(py::module& m) + +void initSunBindings(rh3dmpymodule& m) { py::class_(m, "Sun") .def(py::init<>()) @@ -143,7 +139,7 @@ void initSunBindings(py::module& m) .def_static("SunColorFromAltitude", &BND_File3dmSun::GetSunColorFromAltitude) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_sun.h b/src/bindings/bnd_sun.h index 26e79047..06efe762 100644 --- a/src/bindings/bnd_sun.h +++ b/src/bindings/bnd_sun.h @@ -4,14 +4,7 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSunBindings(py::module_& m); -#else -namespace py = pybind11; -void initSunBindings(py::module& m); -#endif - +void initSunBindings(rh3dmpymodule& m); #else void initSunBindings(void* m); #endif diff --git a/src/bindings/bnd_surface.cpp b/src/bindings/bnd_surface.cpp index 118d0982..734ec745 100644 --- a/src/bindings/bnd_surface.cpp +++ b/src/bindings/bnd_surface.cpp @@ -124,12 +124,8 @@ BND_TUPLE BND_Surface::GetNurbsFormParameterFromSurfaceParameter(double surfaceS #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSurfaceBindings(py::module_& m){} -#else -namespace py = pybind11; -void initSurfaceBindings(py::module& m) + +void initSurfaceBindings(rh3dmpymodule& m) { py::class_(m, "Surface") .def_property_readonly("IsSolid", &BND_Surface::IsSolid) @@ -158,7 +154,7 @@ void initSurfaceBindings(py::module& m) .def("GetNurbsFormParameterFromSurfaceParameter", &BND_Surface::GetNurbsFormParameterFromSurfaceParameter, py::arg("surfaceS"), py::arg("surfaceT")) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_surface.h b/src/bindings/bnd_surface.h index b76ad04a..ca5b6ef2 100644 --- a/src/bindings/bnd_surface.h +++ b/src/bindings/bnd_surface.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSurfaceBindings(py::module_& m); -#else -namespace py = pybind11; -void initSurfaceBindings(py::module& m); -#endif - +void initSurfaceBindings(rh3dmpymodule& m); #else void initSurfaceBindings(void* m); #endif diff --git a/src/bindings/bnd_surfaceproxy.cpp b/src/bindings/bnd_surfaceproxy.cpp index eae6a00e..b79b27e5 100644 --- a/src/bindings/bnd_surfaceproxy.cpp +++ b/src/bindings/bnd_surfaceproxy.cpp @@ -17,17 +17,13 @@ BND_SurfaceProxy::BND_SurfaceProxy() #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSurfaceProxyBindings(py::module_& m){} -#else -namespace py = pybind11; -void initSurfaceProxyBindings(py::module& m) + +void initSurfaceProxyBindings(rh3dmpymodule& m) { py::class_(m, "SurfaceProxy") ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_surfaceproxy.h b/src/bindings/bnd_surfaceproxy.h index 10795c3f..41fb55c9 100644 --- a/src/bindings/bnd_surfaceproxy.h +++ b/src/bindings/bnd_surfaceproxy.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initSurfaceProxyBindings(py::module_& m); -#else -namespace py = pybind11; -void initSurfaceProxyBindings(py::module& m); -#endif - +void initSurfaceProxyBindings(rh3dmpymodule& m); #else void initSurfaceProxyBindings(void* m); #endif diff --git a/src/bindings/bnd_texture.cpp b/src/bindings/bnd_texture.cpp index 37428f77..3c1acfb4 100644 --- a/src/bindings/bnd_texture.cpp +++ b/src/bindings/bnd_texture.cpp @@ -78,12 +78,8 @@ void BND_Environment::SetTrackedPointer(ON_Environment* env, const ON_ModelCompo ////////////////////////////////////////////////////////////////////////////// #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initEnvironmentBindings(py::module_& m){} -#else -namespace py = pybind11; -void initEnvironmentBindings(py::module& m) + +void initEnvironmentBindings(rh3dmpymodule& m) { py::class_(m, "Environment") .def(py::init<>()) @@ -92,7 +88,7 @@ void initEnvironmentBindings(py::module& m) .def_property("BackgroundProjection", &BND_Environment::BackgroundProjection, &BND_Environment::SetBackgroundProjection) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_texture.h b/src/bindings/bnd_texture.h index 74ac3e07..5254a4f7 100644 --- a/src/bindings/bnd_texture.h +++ b/src/bindings/bnd_texture.h @@ -4,16 +4,8 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initEnvironmentBindings(py::module_& m); -void initTextureBindings(py::module_& m); -#else -namespace py = pybind11; -void initEnvironmentBindings(py::module& m); -void initTextureBindings(py::module& m); -#endif - +void initEnvironmentBindings(rh3dmpymodule& m); +void initTextureBindings(rh3dmpymodule& m); #else void initEnvironmentBindings(void* m); void initTextureBindings(void* m); diff --git a/src/bindings/bnd_texture_mapping.cpp b/src/bindings/bnd_texture_mapping.cpp index 8edb8235..1344c81e 100644 --- a/src/bindings/bnd_texture_mapping.cpp +++ b/src/bindings/bnd_texture_mapping.cpp @@ -138,12 +138,8 @@ std::tuple BND_TextureMapping::Evaluate(const ON_3dPoint& P, co #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initTextureMappingBindings(py::module_& m){} -#else -namespace py = pybind11; -void initTextureMappingBindings(py::module& m) + +void initTextureMappingBindings(rh3dmpymodule& m) { py::class_(m, "TextureMapping") .def(py::init<>()) @@ -166,7 +162,7 @@ void initTextureMappingBindings(py::module& m) .def("Evaluate", &BND_TextureMapping::Evaluate, py::arg("p"), py::arg("n")) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_texture_mapping.h b/src/bindings/bnd_texture_mapping.h index 1b1d92bc..3a4b4249 100644 --- a/src/bindings/bnd_texture_mapping.h +++ b/src/bindings/bnd_texture_mapping.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initTextureMappingBindings(py::module_& m); -#else -namespace py = pybind11; -void initTextureMappingBindings(py::module& m); -#endif - +void initTextureMappingBindings(rh3dmpymodule& m); #else void initTextureMappingBindings(void* m); #endif diff --git a/src/bindings/bnd_viewport.cpp b/src/bindings/bnd_viewport.cpp index 7654b321..9d3bcb47 100644 --- a/src/bindings/bnd_viewport.cpp +++ b/src/bindings/bnd_viewport.cpp @@ -373,10 +373,8 @@ BND_UUID BND_Viewport::GetId() const #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -void initViewportBindings(py::module_& m){} -#else -void initViewportBindings(py::module& m) + +void initViewportBindings(rh3dmpymodule& m) { py::class_(m, "ViewportInfo") .def(py::init<>()) @@ -417,7 +415,6 @@ void initViewportBindings(py::module& m) ; } #endif -#endif #if defined(ON_WASM_COMPILE) using namespace emscripten; diff --git a/src/bindings/bnd_viewport.h b/src/bindings/bnd_viewport.h index 2491cfe8..84a48fce 100644 --- a/src/bindings/bnd_viewport.h +++ b/src/bindings/bnd_viewport.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initViewportBindings(py::module_& m); -#else -namespace py = pybind11; -void initViewportBindings(py::module& m); -#endif - +void initViewportBindings(rh3dmpymodule& m); #else void initViewportBindings(void* m); #endif diff --git a/src/bindings/bnd_xform.cpp b/src/bindings/bnd_xform.cpp index a0de7e72..ff3fafc6 100644 --- a/src/bindings/bnd_xform.cpp +++ b/src/bindings/bnd_xform.cpp @@ -115,12 +115,8 @@ BND_TUPLE BND_Transform::ToFloatArray(bool rowDominant) const } #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initXformBindings(py::module_& m){} -#else -namespace py = pybind11; -void initXformBindings(py::module& m) + +void initXformBindings(rh3dmpymodule& m) { py::class_(m, "Transform") .def(py::init(), py::arg("diagonalValue")) @@ -184,7 +180,7 @@ void initXformBindings(py::module& m) .value("Rigid", TransformRigidType::Rigid) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_xform.h b/src/bindings/bnd_xform.h index 00b22401..4a901ce9 100644 --- a/src/bindings/bnd_xform.h +++ b/src/bindings/bnd_xform.h @@ -3,14 +3,7 @@ #pragma once #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initXformBindings(py::module_& m); -#else -namespace py = pybind11; -void initXformBindings(py::module& m); -#endif - +void initXformBindings(rh3dmpymodule& m); #else void initXformBindings(void* m); #endif From 42f8b6c416476e6aea43bd47155960797148ad27 Mon Sep 17 00:00:00 2001 From: fraguada Date: Tue, 6 Aug 2024 12:43:23 +0200 Subject: [PATCH 08/27] build nanobind before linking --- src/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ebc77795..04dbe260 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -109,6 +109,8 @@ if (${RHINO3DM_PY}) add_definitions(-DON_RUNTIME_LINUX) add_definitions(-DON_CLANG_CONSTRUCTOR_BUG) if(PYTHON_BINDING_LIB STREQUAL "NANOBIND") + #need to build nanobind to link it? + nanobind_build_library(nanobind) nanobind_add_module(_rhino3dm ${bindings_SRC} ${opennurbs_SRC} ${zlib_SRC} ${uuid_SRC}) target_link_libraries(_rhino3dm PRIVATE nanobind) else() @@ -121,6 +123,8 @@ if (${RHINO3DM_PY}) add_library(zlib_static STATIC ${zlib_SRC}) add_library(opennurbs_static STATIC ${opennurbs_SRC}) if(PYTHON_BINDING_LIB STREQUAL "NANOBIND") + #need to build nanobind to link it? + nanobind_build_library(nanobind) nanobind_add_module(_rhino3dm ${bindings_SRC}) target_link_libraries(_rhino3dm PRIVATE nanobind) else() From 7bbce1e348788ecea4dfecf5a323259f943d08b4 Mon Sep 17 00:00:00 2001 From: fraguada Date: Tue, 6 Aug 2024 14:36:49 +0200 Subject: [PATCH 09/27] more cleanup and casting fixes. compiles! --- src/bindings/bindings.cpp | 3 -- src/bindings/bindings.h | 3 ++ src/bindings/bnd_annotationbase.cpp | 6 ---- src/bindings/bnd_boundingbox.cpp | 14 ++------- src/bindings/bnd_brep.cpp | 8 ----- src/bindings/bnd_color.cpp | 31 ++++++------------- src/bindings/bnd_defines.h | 5 --- src/bindings/bnd_extensions.cpp | 40 +++++++++++++++++++----- src/bindings/bnd_object.cpp | 2 +- src/bindings/bnd_point.cpp | 48 +++++++++++------------------ src/bindings/bnd_uuid.cpp | 13 +++----- src/bindings/bnd_uuid.h | 5 --- src/bindings/bnd_viewport.cpp | 6 ---- 13 files changed, 70 insertions(+), 114 deletions(-) diff --git a/src/bindings/bindings.cpp b/src/bindings/bindings.cpp index 554affc3..47027bb6 100644 --- a/src/bindings/bindings.cpp +++ b/src/bindings/bindings.cpp @@ -13,7 +13,6 @@ EMSCRIPTEN_BINDINGS(rhino3dm) { ON::Begin(); initFileUtilitiesBindings(m); - /* initDefines(m); initIntersectBindings(m); initPolylineBindings(m); @@ -84,8 +83,6 @@ EMSCRIPTEN_BINDINGS(rhino3dm) { initDracoBindings(m); initRTreeBindings(m); initLinetypeBindings(m); - */ - } #if defined(ON_PYTHON_COMPILE) diff --git a/src/bindings/bindings.h b/src/bindings/bindings.h index 00d36e94..9f8e2b27 100644 --- a/src/bindings/bindings.h +++ b/src/bindings/bindings.h @@ -11,6 +11,7 @@ #include #include #include + #include namespace py = nanobind; typedef nanobind::module_ rh3dmpymodule; #define RH3DM_PYTHON_BINDING(name, variable) NB_MODULE(name, variable) @@ -19,11 +20,13 @@ #define def_readonly def_ro #define def_readwrite def_rw #define def_property_readonly_static def_prop_ro_static +#define import import_ #define UNIMPLEMENTED_EXCEPTION throw std::exception() #else #include #include + #include namespace py = pybind11; #define RH3DM_PYTHON_BINDING(name, variable) PYBIND11_MODULE(name, variable) typedef pybind11::module rh3dmpymodule; diff --git a/src/bindings/bnd_annotationbase.cpp b/src/bindings/bnd_annotationbase.cpp index c7bcf46f..34fcce5a 100644 --- a/src/bindings/bnd_annotationbase.cpp +++ b/src/bindings/bnd_annotationbase.cpp @@ -1,11 +1,5 @@ #include "bindings.h" -#if defined(NANOBIND) -namespace py = nanobind; -#else -namespace py = pybind11; -#endif - BND_AnnotationBase::BND_AnnotationBase() { } diff --git a/src/bindings/bnd_boundingbox.cpp b/src/bindings/bnd_boundingbox.cpp index 8d39e3cf..089a1096 100644 --- a/src/bindings/bnd_boundingbox.cpp +++ b/src/bindings/bnd_boundingbox.cpp @@ -1,11 +1,5 @@ #include "bindings.h" -#if defined(NANOBIND) -namespace py = nanobind; -#else -namespace py = pybind11; -#endif - BND_BoundingBox::BND_BoundingBox(const ON_3dPoint& min, const ON_3dPoint& max) : m_bbox(min, max) { @@ -104,19 +98,15 @@ py::dict BND_BoundingBox::Encode() const return d; } -#if defined(NANOBIND) -// TODO: BND_BoundingBox::Decode for NANOBIND -#else BND_BoundingBox* BND_BoundingBox::Decode(py::dict jsonObject) { ON_BoundingBox bbox; - py::dict d = jsonObject["Min"].cast(); + py::dict d = py::cast(jsonObject["Min"]); bbox.m_min = PointFromDict(d); - d = jsonObject["Max"].cast(); + d = py::cast(jsonObject["Max"]); bbox.m_max = PointFromDict(d); return new BND_BoundingBox(bbox); } -#endif #endif diff --git a/src/bindings/bnd_brep.cpp b/src/bindings/bnd_brep.cpp index f3d75360..1d696304 100644 --- a/src/bindings/bnd_brep.cpp +++ b/src/bindings/bnd_brep.cpp @@ -1,13 +1,5 @@ #include "bindings.h" -#if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -#else -namespace py = pybind11; -#endif -#endif - BND_BrepEdge::BND_BrepEdge(ON_BrepEdge* edge, const ON_ModelComponentReference* compref) { m_edge = edge; diff --git a/src/bindings/bnd_color.cpp b/src/bindings/bnd_color.cpp index 14d5245c..76206c55 100644 --- a/src/bindings/bnd_color.cpp +++ b/src/bindings/bnd_color.cpp @@ -2,47 +2,34 @@ #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -#else -namespace py = pybind11; -#endif - BND_Color ON_Color_to_Binding(const ON_Color& color) { return py::make_tuple(color.Red(), color.Green(), color.Blue(), 255 - color.Alpha()); } -#if defined(NANOBIND) -// TODO: Binding_to_ON_Color is not implemented in nanobind -#else ON_Color Binding_to_ON_Color(const BND_Color& color) { - int r = color[0].cast(); - int g = color[1].cast(); - int b = color[2].cast(); - int a = color[3].cast(); + int r = py::cast(color[0]); + int g = py::cast(color[1]); + int b = py::cast(color[2]); + int a = py::cast(color[3]); return ON_Color(r, g, b, 255-a); } -#endif BND_Color4f ON_4fColor_to_Binding(const ON_4fColor& color) { return py::make_tuple(color.Red(), color.Green(), color.Blue(), color.Alpha()); } -#if defined(NANOBIND) -// TODO: Binding_to_ON_4fColor is not implemented in nanobind -#else + ON_4fColor Binding_to_ON_4fColor(const BND_Color4f& color) { - float r = color[0].cast(); - float g = color[1].cast(); - float b = color[2].cast(); - float a = color[3].cast(); + float r = py::cast(color[0]); + float g = py::cast(color[1]); + float b = py::cast(color[2]); + float a = py::cast(color[3]); return ON_4fColor(r, g, b, a); } -#endif #endif diff --git a/src/bindings/bnd_defines.h b/src/bindings/bnd_defines.h index a6c84ee8..175fef6b 100644 --- a/src/bindings/bnd_defines.h +++ b/src/bindings/bnd_defines.h @@ -5,11 +5,6 @@ #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -#else -namespace py = pybind11; -#endif void initDefines(rh3dmpymodule& m); py::dict PointToDict(const ON_3dPoint& point); diff --git a/src/bindings/bnd_extensions.cpp b/src/bindings/bnd_extensions.cpp index 3f5b09a5..4bab7cb7 100644 --- a/src/bindings/bnd_extensions.cpp +++ b/src/bindings/bnd_extensions.cpp @@ -1646,12 +1646,8 @@ struct PyBNDIterator { #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -void initExtensionsBindings(py::module_& m){} -#else -namespace py = pybind11; -void initExtensionsBindings(py::module& m) + +void initExtensionsBindings(rh3dmpymodule& m) { py::class_(m, "File3dmPlugInData") ; @@ -1678,7 +1674,9 @@ void initExtensionsBindings(py::module& m) py::class_(m, "File3dmObjectTable") .def("__len__", &BND_ONXModel_ObjectTable::Count) .def("__getitem__", &BND_ONXModel_ObjectTable::ModelObjectAt) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("AddPoint", &BND_ONXModel_ObjectTable::AddPoint1, py::arg("x"), py::arg("y"), py::arg("z")) .def("AddPoint", &BND_ONXModel_ObjectTable::AddPoint2, py::arg("point")) .def("AddPoint", &BND_ONXModel_ObjectTable::AddPoint4, py::arg("point")) @@ -1714,7 +1712,9 @@ void initExtensionsBindings(py::module& m) py::class_(m, "File3dmMaterialTable") .def("__len__", &BND_File3dmMaterialTable::Count) .def("__getitem__", &BND_File3dmMaterialTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("Add", &BND_File3dmMaterialTable::Add, py::arg("material")) .def("FindIndex", &BND_File3dmMaterialTable::FindIndex, py::arg("index")) .def("FindId", &BND_File3dmMaterialTable::FindId, py::arg("id")) @@ -1730,7 +1730,9 @@ void initExtensionsBindings(py::module& m) .def("__len__", &BND_File3dmLinetypeTable::Count) .def("__getitem__", static_cast(&BND_File3dmLinetypeTable::FindIndex)) .def("__getitem__", static_cast(&BND_File3dmLinetypeTable::FindId)) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("Add", &BND_File3dmLinetypeTable::Add, py::arg("linetype")) .def("Delete", &BND_File3dmLinetypeTable::Delete, py::arg("id")) .def("FindIndex", &BND_File3dmLinetypeTable::FindIndex, py::arg("index")) @@ -1751,7 +1753,9 @@ void initExtensionsBindings(py::module& m) py::class_(m, "File3dmBitmapTable") .def("__len__", &BND_File3dmBitmapTable::Count) .def("__getitem__", &BND_File3dmBitmapTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("Add", &BND_File3dmBitmapTable::Add, py::arg("bitmap")) .def("FindIndex", &BND_File3dmBitmapTable::FindIndex, py::arg("index")) .def("FindId", &BND_File3dmBitmapTable::FindId, py::arg("id")) @@ -1765,7 +1769,9 @@ void initExtensionsBindings(py::module& m) py::class_(m, "File3dmLayerTable") .def("__len__", &BND_File3dmLayerTable::Count) .def("__getitem__", &BND_File3dmLayerTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("Add", &BND_File3dmLayerTable::Add, py::arg("layer")) .def("AddLayer", &BND_File3dmLayerTable::AddLayer, py::arg("name"), py::arg("color")) .def("FindName", &BND_File3dmLayerTable::FindName, py::arg("name"), py::arg("parentId")) @@ -1781,7 +1787,9 @@ void initExtensionsBindings(py::module& m) py::class_(m, "File3dmGroupTable") .def("__len__", &BND_File3dmGroupTable::Count) .def("__getitem__", &BND_File3dmGroupTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("Add", &BND_File3dmGroupTable::Add, py::arg("group")) .def("Delete", &BND_File3dmGroupTable::Delete, py::arg("group")) .def("Delete", &BND_File3dmGroupTable::DeleteIndex, py::arg("index")) @@ -1799,7 +1807,9 @@ void initExtensionsBindings(py::module& m) py::class_(m, "File3dmDimStyleTable") .def("__len__", &BND_File3dmDimStyleTable::Count) .def("__getitem__", &BND_File3dmDimStyleTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("Add", &BND_File3dmDimStyleTable::Add, py::arg("dimstyle")) .def("FindIndex", &BND_File3dmDimStyleTable::FindIndex, py::arg("index")) .def("FindId", &BND_File3dmDimStyleTable::FindId, py::arg("id")) @@ -1813,7 +1823,9 @@ void initExtensionsBindings(py::module& m) py::class_(m, "File3dmInstanceDefinitionTable") .def("__len__", &BND_File3dmInstanceDefinitionTable::Count) .def("__getitem__", &BND_File3dmInstanceDefinitionTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("AddInstanceDefinition", &BND_File3dmInstanceDefinitionTable::AddInstanceDefinition, py::arg("idef")) .def("Add", &BND_File3dmInstanceDefinitionTable::Add, py::arg("name"), py::arg("description"), py::arg("url"), py::arg("urlTag"), py::arg("basePoint"), py::arg("geometry"), py::arg("attributes")) .def("FindIndex", &BND_File3dmInstanceDefinitionTable::FindIndex, py::arg("index")) @@ -1829,7 +1841,9 @@ void initExtensionsBindings(py::module& m) .def("__len__", &BND_File3dmViewTable::Count) .def("__getitem__", &BND_File3dmViewTable::GetItem) .def("__setitem__", &BND_File3dmViewTable::SetItem) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("Add", &BND_File3dmViewTable::Add, py::arg("view")) ; @@ -1856,7 +1870,9 @@ void initExtensionsBindings(py::module& m) py::class_(m, "File3dmEmbeddedFileTable") .def("__len__", &BND_File3dmEmbeddedFileTable::Count) .def("__getitem__", &BND_File3dmEmbeddedFileTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("Add", &BND_File3dmEmbeddedFileTable::Add, py::arg("embedded_file")) .def("FindIndex", &BND_File3dmEmbeddedFileTable::FindIndex, py::arg("index")) ////.def("FindId", &BND_File3dmEmbeddedFileTable::FindId, py::arg("id")) @@ -1869,7 +1885,9 @@ void initExtensionsBindings(py::module& m) py::class_(m, "File3dmRenderContentTable") .def("__len__", &BND_File3dmRenderContentTable::Count) .def("__getitem__", &BND_File3dmRenderContentTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("Add", &BND_File3dmRenderContentTable::Add, py::arg("render_content")) .def("FindIndex", &BND_File3dmRenderContentTable::FindIndex, py::arg("index")) .def("FindId", &BND_File3dmRenderContentTable::FindId, py::arg("id")) @@ -1885,7 +1903,9 @@ void initExtensionsBindings(py::module& m) .def(py::init(), py::arg("other")) .def("__len__", &BND_File3dmPostEffectTable::Count) .def("__getitem__", &BND_File3dmPostEffectTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif ////.def("Add", &BND_File3dmRenderContentTable::Add, py::arg("render_content")) .def("FindIndex", &BND_File3dmPostEffectTable::FindIndex, py::arg("index")) .def("FindId", &BND_File3dmPostEffectTable::FindId, py::arg("id")) @@ -1901,7 +1921,9 @@ void initExtensionsBindings(py::module& m) .def(py::init(), py::arg("other")) .def("__len__", &BND_File3dmDecalTable::Count) .def("__getitem__", &BND_File3dmDecalTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("FindIndex", &BND_File3dmDecalTable::FindIndex, py::arg("index")) ; @@ -1926,7 +1948,9 @@ void initExtensionsBindings(py::module& m) py::class_(m, "File3dmShutLiningCurveTable") .def("__len__", &BND_File3dmShutLiningCurveTable::Count) .def("__getitem__", &BND_File3dmShutLiningCurveTable::FindIndex) +#if !defined(NANOBIND) .def("__iter__", [](py::object s) { return PyBNDIterator(s.cast(), s); }) +#endif .def("Add", &BND_File3dmShutLiningCurveTable::Add, py::arg("id")) .def("FindIndex", &BND_File3dmShutLiningCurveTable::FindIndex, py::arg("index")) .def("FindId", &BND_File3dmShutLiningCurveTable::FindId, py::arg("id")) @@ -1937,10 +1961,12 @@ void initExtensionsBindings(py::module& m) .def_static("Read", &BND_ONXModel::Read, py::arg("path")) .def_static("ReadNotes", &BND_ONXModel::ReadNotes, py::arg("path")) .def_static("ReadArchiveVersion", &BND_ONXModel::ReadArchiveVersion, py::arg("path")) +/* .def_static("FromByteArray", [](py::buffer b) { py::buffer_info info = b.request(); return BND_ONXModel::FromByteArray(static_cast(info.size), info.ptr); }) + */ .def("Write", &BND_ONXModel::Write, py::arg("path"), py::arg("version")=0) .def_property("StartSectionComments", &BND_ONXModel::GetStartSectionComments, &BND_ONXModel::SetStartSectionComments) .def_property("ApplicationName", &BND_ONXModel::GetApplicationName, &BND_ONXModel::SetApplicationName) @@ -1976,7 +2002,7 @@ void initExtensionsBindings(py::module& m) .def("RdkXml", &BND_ONXModel::RdkXml) ; } -#endif + #endif #if defined(ON_WASM_COMPILE) diff --git a/src/bindings/bnd_object.cpp b/src/bindings/bnd_object.cpp index e6f3ff7b..681deec8 100644 --- a/src/bindings/bnd_object.cpp +++ b/src/bindings/bnd_object.cpp @@ -1451,7 +1451,7 @@ BND_DICT BND_ArchivableDictionary::DecodeToDictionary(BND_DICT jsonObject) } #if defined(ON_PYTHON_COMPILE) if (!archive.EndReadDictionaryEntry()) - throw py::cast_error();; + throw py::cast_error(); #else archive.EndReadDictionaryEntry(); #endif diff --git a/src/bindings/bnd_point.cpp b/src/bindings/bnd_point.cpp index 035c6440..8616803d 100644 --- a/src/bindings/bnd_point.cpp +++ b/src/bindings/bnd_point.cpp @@ -1,13 +1,4 @@ #include "bindings.h" -#if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -#else -namespace py = pybind11; -#include -#endif -#endif - BND_Interval::BND_Interval(const ON_Interval& i) { @@ -39,17 +30,15 @@ ON_3dPoint BND_Point3d::Transform(const ON_3dPoint& pt, const BND_Transform& tra #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -void initPointBindings(py::module_& m){} -#else -static ON_3dPoint GetUnsetPoint3d(pybind11::object /*self*/) + +static ON_3dPoint GetUnsetPoint3d(py::object /*self*/) { return ON_3dPoint::UnsetPoint; } -static pybind11::dict EncodePoint2d(const ON_2dPoint& pt) +static py::dict EncodePoint2d(const ON_2dPoint& pt) { - pybind11::dict d; + py::dict d; d["X"] = pt.x; d["Y"] = pt.y; return d; @@ -59,34 +48,34 @@ static double GetPoint3dX(const ON_3dPoint& pt) { return pt.x; } -static pybind11::dict EncodePoint3d(const ON_3dPoint& pt) +static py::dict EncodePoint3d(const ON_3dPoint& pt) { - pybind11::dict d; + py::dict d; d["X"] = pt.x; d["Y"] = pt.y; d["Z"] = pt.z; return d; } -static pybind11::dict EncodePoint4d(const ON_4dPoint& pt) +static py::dict EncodePoint4d(const ON_4dPoint& pt) { - pybind11::dict d; + py::dict d; d["X"] = pt.x; d["Y"] = pt.y; d["Z"] = pt.z; d["W"] = pt.w; return d; } -static pybind11::dict EncodeVector2d(const ON_2dVector& v) +static py::dict EncodeVector2d(const ON_2dVector& v) { - pybind11::dict d; + py::dict d; d["X"] = v.x; d["Y"] = v.y; return d; } -static pybind11::dict EncodeVector3d(const ON_3dVector& v) +static py::dict EncodeVector3d(const ON_3dVector& v) { - pybind11::dict d; + py::dict d; d["X"] = v.x; d["Y"] = v.y; d["Z"] = v.z; @@ -225,24 +214,24 @@ static double ON_3dVectorDotProduct(const ON_3dVector& a, const ON_3dVector& b) } -static pybind11::dict EncodePoint2f(const ON_2fPoint& pt) +static py::dict EncodePoint2f(const ON_2fPoint& pt) { - pybind11::dict d; + py::dict d; d["X"] = pt.x; d["Y"] = pt.y; return d; } -static pybind11::dict EncodePoint3f(const ON_3fPoint& pt) +static py::dict EncodePoint3f(const ON_3fPoint& pt) { - pybind11::dict d; + py::dict d; d["X"] = pt.x; d["Y"] = pt.y; d["Z"] = pt.z; return d; } -static pybind11::dict EncodeVector3f(const ON_3fVector& v) +static py::dict EncodeVector3f(const ON_3fVector& v) { - pybind11::dict d; + py::dict d; d["X"] = v.x; d["Y"] = v.y; d["Z"] = v.z; @@ -421,7 +410,6 @@ void initPointBindings(rh3dmpymodule& m) .def("__repr__", &ReprInterval); } -#endif #else diff --git a/src/bindings/bnd_uuid.cpp b/src/bindings/bnd_uuid.cpp index c6e24fc3..2c9fd824 100644 --- a/src/bindings/bnd_uuid.cpp +++ b/src/bindings/bnd_uuid.cpp @@ -1,30 +1,26 @@ #include "bindings.h" #if defined(ON_PYTHON_COMPILE) -#if defined(NANOBIND) -namespace py = nanobind; -#else -namespace py = pybind11; -static pybind11::object make_uuid; +static py::object make_uuid; BND_UUID ON_UUID_to_Binding(const ON_UUID& id) { if (make_uuid.ptr() == nullptr) { - pybind11::module uuid_module = pybind11::module::import("uuid"); + rh3dmpymodule uuid_module = rh3dmpymodule::import("uuid"); make_uuid = uuid_module.attr("UUID"); } char s[37]; memset(s, 0, sizeof(s)); char* suuid = ON_UuidToString(id, s); - pybind11::object guid = make_uuid(suuid); + py::object guid = make_uuid(suuid); return guid; } ON_UUID Binding_to_ON_UUID(const BND_UUID& id) { - std::string s = pybind11::str(id); + std::string s = py::cast(id); return ON_UuidFromString(s.c_str()); } @@ -39,7 +35,6 @@ std::vector ON_SimpleArrayUUID_to_Binding(const ON_SimpleArray Date: Wed, 7 Aug 2024 22:23:45 +0200 Subject: [PATCH 10/27] Switch back to pybind11 in setup.py before merge to dev --- setup.py | 4 ++-- src/bindings/bindings.cpp | 23 ++++++++++++++++++++++ src/bindings/bindings.h | 23 ++++++++++++++++++++++ src/dotnet/opennurbs/opennurbs_viewport.cs | 23 ++++++++++++++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 12dc1dda..51109497 100644 --- a/setup.py +++ b/setup.py @@ -65,8 +65,8 @@ def build_extension(self, ext): print("extdir = " + extdir) print("sourcedir" + ext.sourcedir) - #cmake_args = ['cmake', f'-DPYTHON_EXECUTABLE:FILEPATH={pyexec}'] - cmake_args = ['cmake', f'-DPYTHON_EXECUTABLE:FILEPATH={pyexec}', f'-DPYTHON_BINDING_LIB=NANOBIND'] + cmake_args = ['cmake', f'-DPYTHON_EXECUTABLE:FILEPATH={pyexec}'] + #cmake_args = ['cmake', f'-DPYTHON_EXECUTABLE:FILEPATH={pyexec}', f'-DPYTHON_BINDING_LIB=NANOBIND'] cfg = 'Debug' if self.debug else 'Release' build_args = ['--config', cfg] diff --git a/src/bindings/bindings.cpp b/src/bindings/bindings.cpp index 47027bb6..92bb00ac 100644 --- a/src/bindings/bindings.cpp +++ b/src/bindings/bindings.cpp @@ -116,6 +116,29 @@ BND_TUPLE NullTuple() #endif } +BND_LIST CreateList() +{ +#if defined(ON_PYTHON_COMPILE) + BND_LIST rc = py::list(); +#else + emscripten::val rc(emscripten::val::array()); +#endif + return rc; +} + +BND_LIST NullList() +{ +#if defined(ON_PYTHON_COMPILE) +#if defined(NANOBIND) + return py::list(); +#else + return py::none(); +#endif +#else + return emscripten::val::null(); +#endif +} + BND_DateTime CreateDateTime(struct tm t) { #if defined(ON_PYTHON_COMPILE) diff --git a/src/bindings/bindings.h b/src/bindings/bindings.h index 9f8e2b27..f5675241 100644 --- a/src/bindings/bindings.h +++ b/src/bindings/bindings.h @@ -77,6 +77,29 @@ void SetTuple(BND_TUPLE& tuple, int index, const T& value) #endif } +BND_LIST CreateList(int count); +BND_LIST NullList(); +template +void Insert(BND_LIST& list, int index, const T& value) +{ +#if defined(ON_PYTHON_COMPILE) + list.insert(index, value); +#else + list.set(index, value); +#endif +} + +template +void Append(BND_LIST& list, const T& value) +{ +#if defined(ON_PYTHON_COMPILE) + list.append(value); +#else + const int count = list["length"].as(); + list.set(count++, value); +#endif +} + BND_DateTime CreateDateTime(struct tm t); #include "bnd_color.h" diff --git a/src/dotnet/opennurbs/opennurbs_viewport.cs b/src/dotnet/opennurbs/opennurbs_viewport.cs index ea64a021..871344c3 100644 --- a/src/dotnet/opennurbs/opennurbs_viewport.cs +++ b/src/dotnet/opennurbs/opennurbs_viewport.cs @@ -30,6 +30,29 @@ internal override IntPtr _InternalDuplicate(out bool applymempressure) return UnsafeNativeMethods.ON_Viewport_New(const_ptr_this); } + /// + /// If the viewport has a parent ViewInfo, return a NonConstPtr to the viewport. + /// + /// IntPtr + /// 8.10 + internal override IntPtr NonConstPointer() + { + if(m_parent != null && !IsNonConst) + { + var vi = m_parent as ViewInfo; + if (vi != null) + { + IntPtr pView = vi.NonConstPointer(); + IntPtr v = UnsafeNativeMethods.ON_3dmView_ViewportPointer(pView); + if (v != IntPtr.Zero) + { + return v; + } + } + } + return base.NonConstPointer(); + } + /// /// Initializes a new instance. /// From a0a154b4384ea4e75e9301f9b6ccb5e1cd3cfafa Mon Sep 17 00:00:00 2001 From: fraguada Date: Wed, 7 Aug 2024 22:46:50 +0200 Subject: [PATCH 11/27] some more things to revert for pybind11 --- src/bindings/bindings.h | 1 + src/bindings/bnd_nurbscurve.cpp | 4 ++-- src/bindings/bnd_nurbssurface.cpp | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/bindings/bindings.h b/src/bindings/bindings.h index f5675241..da98073c 100644 --- a/src/bindings/bindings.h +++ b/src/bindings/bindings.h @@ -59,6 +59,7 @@ typedef emscripten::val BND_Color; typedef emscripten::val BND_Color4f; typedef emscripten::val BND_TUPLE; typedef emscripten::val BND_DateTime; +typedef emscripten::val BND_LIST; #endif BND_TUPLE CreateTuple(int count); diff --git a/src/bindings/bnd_nurbscurve.cpp b/src/bindings/bnd_nurbscurve.cpp index 0dfa7d8e..9c885237 100644 --- a/src/bindings/bnd_nurbscurve.cpp +++ b/src/bindings/bnd_nurbscurve.cpp @@ -225,7 +225,7 @@ BND_BezierCurve* BND_NurbsCurve::ConvertSpanToBezier(int index) const void initNurbsCurveBindings(rh3dmpymodule& m) { - py::class_(m, "NurbsCurveKnotList" /* , py::buffer_protocol()*/) + py::class_(m, "NurbsCurveKnotList", py::buffer_protocol()) .def("__len__", &BND_NurbsCurveKnotList::Count) .def("__getitem__", &BND_NurbsCurveKnotList::GetKnot) .def("__setitem__", &BND_NurbsCurveKnotList::SetKnot) @@ -254,7 +254,7 @@ void initNurbsCurveBindings(rh3dmpymodule& m) ; ; - py::class_(m, "NurbsCurvePointList"/*, py::buffer_protocol()*/) + py::class_(m, "NurbsCurvePointList", py::buffer_protocol()) .def("__len__", &BND_NurbsCurvePointList::Count) .def("__getitem__", &BND_NurbsCurvePointList::GetControlPoint) .def("__setitem__", &BND_NurbsCurvePointList::SetControlPoint) diff --git a/src/bindings/bnd_nurbssurface.cpp b/src/bindings/bnd_nurbssurface.cpp index 80600ffa..7d5696e3 100644 --- a/src/bindings/bnd_nurbssurface.cpp +++ b/src/bindings/bnd_nurbssurface.cpp @@ -200,7 +200,7 @@ BND_NurbsSurfacePointList BND_NurbsSurface::Points() void initNurbsSurfaceBindings(rh3dmpymodule& m) { - py::class_(m, "NurbsSurfaceKnotList" /* , py::buffer_protocol() */) + py::class_(m, "NurbsSurfaceKnotList", py::buffer_protocol()) .def("__len__", &BND_NurbsSurfaceKnotList::Count) .def("__getitem__", &BND_NurbsSurfaceKnotList::GetKnot) .def("__setitem__", &BND_NurbsSurfaceKnotList::SetKnot) @@ -228,7 +228,7 @@ void initNurbsSurfaceBindings(rh3dmpymodule& m) .def("SuperfluousKnot", &BND_NurbsSurfaceKnotList::SuperfluousKnot, py::arg("start")) ; - py::class_(m, "NurbsSurfacePointList"/* , py::buffer_protocol() */) + py::class_(m, "NurbsSurfacePointList", py::buffer_protocol()) .def("__len__", &BND_NurbsSurfacePointList::Count) .def_property_readonly("CountU", &BND_NurbsSurfacePointList::CountU) .def_property_readonly("CountV", &BND_NurbsSurfacePointList::CountV) From 381f91277caba325faa31eff46dfa977897a565d Mon Sep 17 00:00:00 2001 From: fraguada Date: Wed, 7 Aug 2024 22:53:04 +0200 Subject: [PATCH 12/27] fix for emscripten --- src/bindings/bindings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/bindings.h b/src/bindings/bindings.h index da98073c..c8d39c56 100644 --- a/src/bindings/bindings.h +++ b/src/bindings/bindings.h @@ -96,7 +96,7 @@ void Append(BND_LIST& list, const T& value) #if defined(ON_PYTHON_COMPILE) list.append(value); #else - const int count = list["length"].as(); + int count = list["length"].as(); list.set(count++, value); #endif } From 20c258e7c6cbbae1100a878acea169731d6301fd Mon Sep 17 00:00:00 2001 From: fraguada Date: Wed, 7 Aug 2024 23:27:33 +0200 Subject: [PATCH 13/27] add ctor to ViewInfo --- src/bindings/bnd_3dm_settings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bindings/bnd_3dm_settings.cpp b/src/bindings/bnd_3dm_settings.cpp index 7e1561a5..8797f960 100644 --- a/src/bindings/bnd_3dm_settings.cpp +++ b/src/bindings/bnd_3dm_settings.cpp @@ -235,6 +235,7 @@ void init3dmSettingsBindings(void*) ; class_("ViewInfo") + .constructor<>() .property("name", &BND_ViewInfo::GetName, &BND_ViewInfo::SetName) .property("wallpaperName", &BND_ViewInfo::GetWallpaperFilename) .property("showWallpaperInGrayScale", &BND_ViewInfo::ShowWallpaperInGrayScale, &BND_ViewInfo::SetShowWallpaperInGrayScale) From 7cdeeb4acceac7ee3efcf8eb4f925b275ae63e85 Mon Sep 17 00:00:00 2001 From: fraguada Date: Thu, 8 Aug 2024 00:08:53 +0200 Subject: [PATCH 14/27] Some ifdefs to make it easier to switch between oybind and nanobind --- src/bindings/bnd_nurbscurve.cpp | 8 ++++++++ src/bindings/bnd_nurbssurface.cpp | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/bindings/bnd_nurbscurve.cpp b/src/bindings/bnd_nurbscurve.cpp index 9c885237..aa3035ab 100644 --- a/src/bindings/bnd_nurbscurve.cpp +++ b/src/bindings/bnd_nurbscurve.cpp @@ -225,7 +225,11 @@ BND_BezierCurve* BND_NurbsCurve::ConvertSpanToBezier(int index) const void initNurbsCurveBindings(rh3dmpymodule& m) { +#if defined(NANOBIND) // temp workaround for buffer protocol + py::class_(m, "NurbsCurveKnotList") +#else py::class_(m, "NurbsCurveKnotList", py::buffer_protocol()) +#endif .def("__len__", &BND_NurbsCurveKnotList::Count) .def("__getitem__", &BND_NurbsCurveKnotList::GetKnot) .def("__setitem__", &BND_NurbsCurveKnotList::SetKnot) @@ -254,7 +258,11 @@ void initNurbsCurveBindings(rh3dmpymodule& m) ; ; +#if defined(NANOBIND) // temp workaround for buffer protocol + py::class_(m, "NurbsCurvePointList") +#else py::class_(m, "NurbsCurvePointList", py::buffer_protocol()) +#endif .def("__len__", &BND_NurbsCurvePointList::Count) .def("__getitem__", &BND_NurbsCurvePointList::GetControlPoint) .def("__setitem__", &BND_NurbsCurvePointList::SetControlPoint) diff --git a/src/bindings/bnd_nurbssurface.cpp b/src/bindings/bnd_nurbssurface.cpp index 7d5696e3..959245c3 100644 --- a/src/bindings/bnd_nurbssurface.cpp +++ b/src/bindings/bnd_nurbssurface.cpp @@ -200,7 +200,11 @@ BND_NurbsSurfacePointList BND_NurbsSurface::Points() void initNurbsSurfaceBindings(rh3dmpymodule& m) { +#if defined(NANOBIND) + py::class_(m, "NurbsSurfaceKnotList") +#else py::class_(m, "NurbsSurfaceKnotList", py::buffer_protocol()) +#endif .def("__len__", &BND_NurbsSurfaceKnotList::Count) .def("__getitem__", &BND_NurbsSurfaceKnotList::GetKnot) .def("__setitem__", &BND_NurbsSurfaceKnotList::SetKnot) @@ -228,7 +232,11 @@ void initNurbsSurfaceBindings(rh3dmpymodule& m) .def("SuperfluousKnot", &BND_NurbsSurfaceKnotList::SuperfluousKnot, py::arg("start")) ; +#if defined(NANOBIND) + py::class_(m, "NurbsSurfacePointList") +#else py::class_(m, "NurbsSurfacePointList", py::buffer_protocol()) +#endif .def("__len__", &BND_NurbsSurfacePointList::Count) .def_property_readonly("CountU", &BND_NurbsSurfacePointList::CountU) .def_property_readonly("CountV", &BND_NurbsSurfacePointList::CountV) From a3e7e8007e1cf83f7f0d50c865347a543e6d3a0e Mon Sep 17 00:00:00 2001 From: fraguada Date: Thu, 8 Aug 2024 00:14:18 +0200 Subject: [PATCH 15/27] bump version numbers --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- setup.py | 2 +- src/dotnet/Properties/AssemblyInfo.cs | 4 ++-- src/dotnet/Rhino3dm.csproj | 2 +- src/rhino3dm/__init__.py | 2 +- src/version.txt | 2 +- 7 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dbee8ed..4fb50f68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [8.10.0] - UNRELEASED + +diff: + +### Fixed + +- (dotnet) Changes to ViewInfo.Viewport would not set. + +### Changed + +- (py) switching from pybind11 to nanobind + ## [8.9.0] - 2024.07.19 diff: https://github.com/mcneel/rhino3dm/compare/8.6.1...8.9.0 diff --git a/package.json b/package.json index 80a83c69..57ffab6a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rhino3dm", - "version": "8.9.0", + "version": "8.10.0-beta", "description": "Node.js package based on OpenNURBS with a RhinoCommon style", "main": "rhino3dm.js", "types": "rhino3dm.d.ts", diff --git a/setup.py b/setup.py index 51109497..c890bfc8 100644 --- a/setup.py +++ b/setup.py @@ -144,7 +144,7 @@ def build_extension(self, ext): setup( name='rhino3dm', - version='8.9.0', + version='8.10.0-beta', author='Robert McNeel & Associates', author_email='steve@mcneel.com', description='Python library based on OpenNURBS with a RhinoCommon style', diff --git a/src/dotnet/Properties/AssemblyInfo.cs b/src/dotnet/Properties/AssemblyInfo.cs index d9e3110d..bdc972e6 100644 --- a/src/dotnet/Properties/AssemblyInfo.cs +++ b/src/dotnet/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Robert McNeel & Associates")] [assembly: AssemblyProduct("Rhino")] -[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Brian Gillespie: 9/22/2010 @@ -74,7 +74,7 @@ //[assembly: AssemblyVersion("6.0.0.1")] //#endif -[assembly: AssemblyVersion("8.9.0.0")] +[assembly: AssemblyVersion("8.10.0.0")] // 2013-12-19, Brian Gillespie // AssemblyFileVersion is set in /src4/version.h diff --git a/src/dotnet/Rhino3dm.csproj b/src/dotnet/Rhino3dm.csproj index 2fc3e7c6..8906df7d 100644 --- a/src/dotnet/Rhino3dm.csproj +++ b/src/dotnet/Rhino3dm.csproj @@ -8,7 +8,7 @@ Rhino3dm true Rhino - 8.9.0 + 8.10.0-beta Rhino3dm mcneel .NET library based on OpenNURBS with a "RhinoCommon" style diff --git a/src/rhino3dm/__init__.py b/src/rhino3dm/__init__.py index c486df9b..07c20d21 100644 --- a/src/rhino3dm/__init__.py +++ b/src/rhino3dm/__init__.py @@ -4,7 +4,7 @@ else: from ._rhino3dm import * -__version__ = '8.9.0' +__version__ = '8.10.0-beta' Point2d.__str__ = lambda self: "{},{}".format(self.X, self.Y) Point3d.__str__ = lambda self: "{},{},{}".format(self.X, self.Y, self.Z) diff --git a/src/version.txt b/src/version.txt index 3ecb3981..28f427ee 100644 --- a/src/version.txt +++ b/src/version.txt @@ -1 +1 @@ -8.9.0 \ No newline at end of file +8.10.0-beta \ No newline at end of file From dfb100a402a594fb154498889f7fc4145148569b Mon Sep 17 00:00:00 2001 From: fraguada Date: Fri, 9 Aug 2024 13:19:55 +0200 Subject: [PATCH 16/27] changing the way we access ViewInfo.Viewport() in js/py --- src/bindings/bnd_3dm_settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/bnd_3dm_settings.cpp b/src/bindings/bnd_3dm_settings.cpp index 8797f960..72af19c8 100644 --- a/src/bindings/bnd_3dm_settings.cpp +++ b/src/bindings/bnd_3dm_settings.cpp @@ -3,7 +3,7 @@ BND_Viewport* BND_ViewInfo::GetViewport() const { - return new BND_Viewport(new ON_Viewport(m_view.m_vp), nullptr); + return new BND_Viewport(const_cast(&m_view.m_vp), nullptr); } void BND_ViewInfo::SetViewport(const BND_Viewport& viewport) From 876db7382c6cdae75ac88cdea778daa2bf9297a5 Mon Sep 17 00:00:00 2001 From: fraguada Date: Fri, 9 Aug 2024 14:03:17 +0200 Subject: [PATCH 17/27] update tests for js and py --- tests/javascript/file3dm.ViewTable.test.js | 15 +++++---------- tests/python/test_File3dm_ViewTable.py | 11 ++++++----- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/tests/javascript/file3dm.ViewTable.test.js b/tests/javascript/file3dm.ViewTable.test.js index c2e75c9d..4b1af2ce 100644 --- a/tests/javascript/file3dm.ViewTable.test.js +++ b/tests/javascript/file3dm.ViewTable.test.js @@ -28,18 +28,13 @@ test('CreateFileWithView', async () => { const vi = new rhino.ViewInfo() vi.name = 'main_js' - //does not work - /* + const loc = [50,50,100] + vi.getViewport().setCameraLocation([50, 50, 100]) - loc = vi.getViewport().cameraLocation //<-- default location - */ + const loc2 = vi.getViewport().cameraLocation - // works - const vp = new rhino.ViewportInfo() - const loc = [50,50,100] - vp.setCameraLocation(loc) - vi.setViewport(vp) file3dm.views().add(vi) + loc3 = vi.getViewport().cameraLocation const bufferWrite = file3dm.toByteArray() fs.writeFileSync('test_createFileWithView.3dm', bufferWrite) @@ -52,6 +47,6 @@ test('CreateFileWithView', async () => { const vp_read = vi_read.getViewport() const loc_read = vp_read.cameraLocation - expect(loc[0] === loc_read[0] && loc[1] === loc_read[1] && loc[2] === loc_read[2]).toBe(true) + expect(JSON.stringify(loc) === JSON.stringify(loc_read) && JSON.stringify(loc2) === JSON.stringify(loc_read) && JSON.stringify(loc3) === JSON.stringify(loc_read)).toBe(true) }) \ No newline at end of file diff --git a/tests/python/test_File3dm_ViewTable.py b/tests/python/test_File3dm_ViewTable.py index 4be47552..c4846990 100644 --- a/tests/python/test_File3dm_ViewTable.py +++ b/tests/python/test_File3dm_ViewTable.py @@ -19,12 +19,13 @@ def test_createFileWithView(self): sphere = rhino3dm.Sphere(rhino3dm.Point3d(x, y, z), 10) file3dm.Objects.AddSphere(sphere, None) - vp = rhino3dm.ViewportInfo() - loc = rhino3dm.Point3d(50, 50, 50) - vp.SetCameraLocation(loc) view = rhino3dm.ViewInfo() view.Name = "Main_py" - view.Viewport = vp + + loc = rhino3dm.Point3d(50, 50, 50) + + view.Viewport.SetCameraLocation(loc) + loc2 = view.Viewport.CameraLocation file3dm.Views.Add(view) @@ -39,7 +40,7 @@ def test_createFileWithView(self): print(loc2.X, loc2.Y, loc2.Z) print(loc_read.X, loc_read.Y, loc_read.Z) - self.assertTrue(loc.X == loc_read.X and loc.Y == loc_read.Y and loc.Z == loc_read.Z) + self.assertTrue(loc == loc_read and loc2 == loc_read) if __name__ == '__main__': print("running tests") From e559fa97f1bb8944217f6966cf06377f774771e3 Mon Sep 17 00:00:00 2001 From: fraguada Date: Fri, 9 Aug 2024 14:29:57 +0200 Subject: [PATCH 18/27] cleanup test --- tests/python/test_File3dm_ViewTable.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/python/test_File3dm_ViewTable.py b/tests/python/test_File3dm_ViewTable.py index c4846990..29a9d848 100644 --- a/tests/python/test_File3dm_ViewTable.py +++ b/tests/python/test_File3dm_ViewTable.py @@ -36,10 +36,6 @@ def test_createFileWithView(self): vi_read = file3dm_read.Views[0] loc_read = vi_read.Viewport.CameraLocation - print(loc.X, loc.Y, loc.Z) - print(loc2.X, loc2.Y, loc2.Z) - print(loc_read.X, loc_read.Y, loc_read.Z) - self.assertTrue(loc == loc_read and loc2 == loc_read) if __name__ == '__main__': From d3ca009836bf8b7bff8edc5148878b7b6a8b2b1f Mon Sep 17 00:00:00 2001 From: fraguada Date: Thu, 22 Aug 2024 11:00:24 +0200 Subject: [PATCH 19/27] update opennurbs to 8.10 --- src/lib/opennurbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/opennurbs b/src/lib/opennurbs index ae65ce66..285c43ce 160000 --- a/src/lib/opennurbs +++ b/src/lib/opennurbs @@ -1 +1 @@ -Subproject commit ae65ce66932fff9d8321de104d885852a5b529a5 +Subproject commit 285c43ce2bd6c917bdc3e3f1eca0da466c1b07d1 From f88ca6ae8fab97986248f3ae8b504dbb56954ba1 Mon Sep 17 00:00:00 2001 From: fraguada Date: Thu, 22 Aug 2024 18:47:40 +0200 Subject: [PATCH 20/27] add file3dm tables test for python --- src/lib/README.md | 4 +++- tests/models/file3dm_stuff.3dm | Bin 0 -> 4013407 bytes tests/python/test_File3dm.py | 41 +++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 tests/models/file3dm_stuff.3dm create mode 100644 tests/python/test_File3dm.py diff --git a/src/lib/README.md b/src/lib/README.md index 2279bad5..1da9e140 100644 --- a/src/lib/README.md +++ b/src/lib/README.md @@ -2,4 +2,6 @@ This directory contains source for external libraries used for compiling rhino3dm - opennurbs 8.x branch -- pybind11 v2.10.1 \ No newline at end of file +- pybind11 v2.10.1 +- draco v1.5.6 (mcneel mod) +- nanobind v2.1.0 \ No newline at end of file diff --git a/tests/models/file3dm_stuff.3dm b/tests/models/file3dm_stuff.3dm new file mode 100644 index 0000000000000000000000000000000000000000..fe41eee51ab66333bc7a4a18b0fa2ba090d6ca39 GIT binary patch literal 4013407 zcmeF)ceGViw(omyd#~MACD}j@o1Ak{F`%NLBBF>H0}3hCvfQPV(RF4gSjwH{8(I|409|f3s`PUaxiO z)2naJ?KwF$Zm)NHy+%zMHoUD~gGLP+G^&%+s6nG9bsIFP+o)O1oVqzJd-dqirO#_! zJ9V#<^J@RD-8*N!u9s`P)~iQvePHLD`+E1uY1AydTJy%7oF^Y>lk;?!K7G6P>e)O; z=fAx{(}s664Ih<$s)O3~?$YzIr`q5DesdB8#zx7?%S_R zkLLQ=-uiZXbb75_<|H`{o78JmuVGG&`;+T!-14@Dx}^5~d-m(vqf7Igc8@i0p8n#& zo&&n}>D9AGm!AEaH&0I0_<^=L57%#()4Pv;NPYYE>Z3PgF0)^+UfsKO?Uyqk`OdPw zv84rD7x6=)swcT*T|EbMyWI=5=YWuI+-qrShXxpmo-*%Q; zb!2gEf9))O*57YvyR51%u<7H;h1bx&PyJ(b3I9dc7XC}WmVA-^U+sHv%>Vnw4NDi! zHa30+7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAq zFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOc zzyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6( z00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC z0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n z1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q z7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJ zU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm? zfB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n z00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO z0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD z3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAq zFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOc zzyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6( z00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC z0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n z1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q z7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJ zU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm? zfB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n z00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO z0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD z3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAq zFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOc zzyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6( z00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC z0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n z1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q z7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJ zU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm? zfB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n z00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO z0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD z3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAq zFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOc zzyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6( z00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC z0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n z1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q z7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJ zU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm? zfB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n z00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO z0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD z3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAq zFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOc zzyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6( z00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC z0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n z1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q z7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJ zU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm? zfB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n z00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO z0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD z3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAq zFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOc zzyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6( z00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC z0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n z1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q z7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJ zU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm? zfB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n z00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO z0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD z3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAq zFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOc zzyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6( z00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC z0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n z1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q z7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJ zU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm? zfB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n z00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO z0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD z3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAq zFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOc zzyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6( z00S7n00uCC0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC z0SsUO0~o*n1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n z1~7mD3}65Q7{CAqFn|FJU;qOczyJm?fB_6(00S7n00uCC0SsUO0~o*n1~7mD3}65Q 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 z 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

K%V~blojlQ{DGC#$p}C7^tSnbQn(2C| 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 d000000094g000O800000003V-Jpcdz007{;+r|I@ literal 0 HcmV?d00001 diff --git a/tests/python/test_File3dm.py b/tests/python/test_File3dm.py new file mode 100644 index 00000000..f5505f83 --- /dev/null +++ b/tests/python/test_File3dm.py @@ -0,0 +1,41 @@ +import rhino3dm +import unittest + +#objective: to test the number of objects in the file3dm tables +class TestFile3dmTables(unittest.TestCase): + def test_read3dmTables(self): + + file3dm = rhino3dm.File3dm.Read('../models/file3dm_stuff.3dm') + + objectTableCnt = len(file3dm.Objects) + layerTableCnt = len(file3dm.Layers) + materialsTableCnt = len(file3dm.Materials) + linetypeTableCnt = len(file3dm.Linetypes) + bitmapsTableCnt = len(file3dm.Bitmaps) + groupTableCnt = len(file3dm.Groups) + idTableCnt = len(file3dm.InstanceDefinitions) + viewTableCnt = len(file3dm.Views) + namedViewsTableCnt = len(file3dm.NamedViews) + pluginDataTableCnt = len(file3dm.PlugInData) + stringTableCnt = len(file3dm.Strings) + embeddedFileTableCnt = len(file3dm.EmbeddedFiles) + renderContentTableCnt = len(file3dm.RenderContent) + + self.assertTrue(objectTableCnt == 22) + self.assertTrue(layerTableCnt == 6) + self.assertTrue(materialsTableCnt == 2) + self.assertTrue(linetypeTableCnt == 6) + self.assertTrue(bitmapsTableCnt == 0) + self.assertTrue(groupTableCnt == 2) + self.assertTrue(idTableCnt == 1) + self.assertTrue(viewTableCnt == 4) + self.assertTrue(namedViewsTableCnt == 2) + self.assertTrue(pluginDataTableCnt == 1) + self.assertTrue(stringTableCnt == 1) + self.assertTrue(embeddedFileTableCnt == 1) + self.assertTrue(renderContentTableCnt == 3) + +if __name__ == '__main__': + print("running tests") + unittest.main() + print("tests complete") \ No newline at end of file From 4004253c2f2e2de6426540e09866ba984057efc6 Mon Sep 17 00:00:00 2001 From: fraguada Date: Thu, 22 Aug 2024 19:00:43 +0200 Subject: [PATCH 21/27] try without debug in ci --- .github/workflows/workflow_ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow_ci.yml b/.github/workflows/workflow_ci.yml index 4ab5dd06..e271159c 100644 --- a/.github/workflows/workflow_ci.yml +++ b/.github/workflows/workflow_ci.yml @@ -267,7 +267,7 @@ jobs: - name: update submodules run: git submodule update --init - name: build python ${{ matrix.python-version }} ${{ matrix.os }} - run: python setup.py bdist_wheel build --debug + run: python setup.py bdist_wheel build #--debug - name: artifacts uses: actions/upload-artifact@v4.3.1 with: From 598f9483018792c47aa319d80d72e8bb07234eab Mon Sep 17 00:00:00 2001 From: fraguada Date: Thu, 22 Aug 2024 21:05:03 +0200 Subject: [PATCH 22/27] small tuneup to workflow ci --- .github/workflows/workflow_ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/workflow_ci.yml b/.github/workflows/workflow_ci.yml index e271159c..37387a93 100644 --- a/.github/workflows/workflow_ci.yml +++ b/.github/workflows/workflow_ci.yml @@ -267,7 +267,7 @@ jobs: - name: update submodules run: git submodule update --init - name: build python ${{ matrix.python-version }} ${{ matrix.os }} - run: python setup.py bdist_wheel build #--debug + run: python setup.py bdist_wheel build --debug - name: artifacts uses: actions/upload-artifact@v4.3.1 with: @@ -393,7 +393,7 @@ jobs: dotnet test test_python_bdist: - name: build python ${{ matrix.python-version }} ${{ matrix.target }} ${{ matrix.os }} bdist + name: test py ${{ matrix.python-version }} ${{ matrix.target }} ${{ matrix.os }} bdist runs-on: ${{ matrix.os }} needs: [build_py_all_bdist] strategy: From 8ba49e6b9c20a9a64ed8efae49d6233e311f4f87 Mon Sep 17 00:00:00 2001 From: fraguada Date: Fri, 13 Sep 2024 13:25:29 +0200 Subject: [PATCH 23/27] try to build release on mcneel/amazonlinux2023 --- .github/workflows/workflow_release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/workflow_release.yml b/.github/workflows/workflow_release.yml index 9382fd0f..600c0c7d 100644 --- a/.github/workflows/workflow_release.yml +++ b/.github/workflows/workflow_release.yml @@ -177,15 +177,15 @@ jobs: include: - os: ubuntu-latest target: linux - #image: mcneel/rhino3dm-dev-amzn2 + image: mcneel/rhino3dm-dev-amazonlinux2023 artifact-path: src/build/linux/librhino3dm_native.so - os: windows-2022 target: windows - #image: "" + image: "" artifact-path: src\build\windows\*\Release\librhino3dm_native.dll - os: macos-14 target: macos - #image: "" + image: "" artifact-path: src/build/macos/Release/librhino3dm_native.dylib fail-fast: false steps: From f61239a40b9c91d7112aa238384165af0e3b5095 Mon Sep 17 00:00:00 2001 From: fraguada Date: Fri, 13 Sep 2024 13:28:27 +0200 Subject: [PATCH 24/27] add container/image back to release workflow --- .github/workflows/workflow_release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/workflow_release.yml b/.github/workflows/workflow_release.yml index 600c0c7d..3f361bb9 100644 --- a/.github/workflows/workflow_release.yml +++ b/.github/workflows/workflow_release.yml @@ -169,8 +169,8 @@ jobs: build_dotnet_os: name: build dotnet ${{ matrix.target }} runs-on: ${{ matrix.os }} - #container: - #image: ${{ matrix.image }} + container: + image: ${{ matrix.image }} strategy: matrix: os: [ubuntu-latest, macos-14, windows-2022] From 8e099b3d46bf954a05325c272e92265dee77df7a Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Sat, 28 Sep 2024 17:17:40 -0700 Subject: [PATCH 25/27] Swap order of "add" arguments. The TypeScript bindings are not reflecting the actual argument order for the `add` method in `File3dmObjectTable`. --- src/js/rhino3dm.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/rhino3dm.d.ts b/src/js/rhino3dm.d.ts index 0bd3eec3..af48c0e5 100644 --- a/src/js/rhino3dm.d.ts +++ b/src/js/rhino3dm.d.ts @@ -3124,11 +3124,11 @@ declare module 'rhino3dm' { addBrep(brep:Brep): string; /** * @description Duplicates the object, then adds a copy of the object to the document. - * @param {ObjectAttributes} attributes * @param {GeometryBase} geometry + * @param {ObjectAttributes} attributes * @returns {string} A unique identifier for the object. */ - add(attributes: ObjectAttributes, geometry: GeometryBase): string; + add(geometry: GeometryBase, attributes: ObjectAttributes): string; /** ... */ addObject(): void; /** From 73999e0929a126073ba46fd6cc5a39b082cafd01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Cort=C3=A9s?= <36660222+pedrocortesark@users.noreply.github.com> Date: Wed, 9 Oct 2024 20:51:19 +0200 Subject: [PATCH 26/27] #642 --- src/bindings/bnd_pointcloud.cpp | 24 ++++++++++++++++++++++++ src/bindings/bnd_pointcloud.h | 1 + 2 files changed, 25 insertions(+) diff --git a/src/bindings/bnd_pointcloud.cpp b/src/bindings/bnd_pointcloud.cpp index 6c84ee77..de270872 100644 --- a/src/bindings/bnd_pointcloud.cpp +++ b/src/bindings/bnd_pointcloud.cpp @@ -802,6 +802,29 @@ BND_DICT BND_PointCloud::ToThreejsJSON() const } +BND_PointCloud* BND_PointCloud::CreateFromThreejsJSON(BND_DICT json) +{ + if (emscripten::val::undefined() == json["data"]) + return nullptr; + emscripten::val attributes = json["data"]["attributes"]; + + std::vector position_array = emscripten::vecFromJSArray(attributes["position"]["array"]); + + ON_PointCloud* pc = new ON_PointCloud(); + + const int vertex_count = position_array.size() / 3; + pc->m_V.SetCapacity(vertex_count); + pc->m_V.SetCount(vertex_count); + memcpy(pc->m_V.Array(), position_array.data(), sizeof(float) * position_array.size()); + + ON_Xform rotation(1); + rotation.RotationZYX(0.0, 0.0, ON_PI / 2.0); + pc->Transform(rotation); + + return new BND_PointCloud(pc, nullptr); +} + + #endif @@ -936,6 +959,7 @@ void initPointCloudBindings(void*) .function("getValues", &BND_PointCloud::GetValues) .function("closestPoint", &BND_PointCloud::ClosestPoint) .function("toThreejsJSON", &BND_PointCloud::ToThreejsJSON) + .class_function("createFromThreejsJSON", &BND_PointCloud::CreateFromThreejsJSON) ; } #endif diff --git a/src/bindings/bnd_pointcloud.h b/src/bindings/bnd_pointcloud.h index 45d91e61..f7381739 100644 --- a/src/bindings/bnd_pointcloud.h +++ b/src/bindings/bnd_pointcloud.h @@ -126,5 +126,6 @@ class BND_PointCloud : public BND_GeometryBase //IEnumerable #if defined(ON_WASM_COMPILE) BND_DICT ToThreejsJSON() const; + static BND_PointCloud CreateFromThreejsJSON(BND_DICT json); #endif }; From bb7f1f78313100a0ae56a91b05af9f701463f261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Cort=C3=A9s?= <36660222+pedrocortesark@users.noreply.github.com> Date: Thu, 10 Oct 2024 09:10:26 +0200 Subject: [PATCH 27/27] #642 Fixed declaration error --- src/bindings/bnd_pointcloud.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/bnd_pointcloud.h b/src/bindings/bnd_pointcloud.h index f7381739..3f5c694e 100644 --- a/src/bindings/bnd_pointcloud.h +++ b/src/bindings/bnd_pointcloud.h @@ -126,6 +126,6 @@ class BND_PointCloud : public BND_GeometryBase //IEnumerable #if defined(ON_WASM_COMPILE) BND_DICT ToThreejsJSON() const; - static BND_PointCloud CreateFromThreejsJSON(BND_DICT json); + static BND_PointCloud* CreateFromThreejsJSON(BND_DICT json); #endif };