From f79fd7f84afb8a56757dc756e98fa7bbfa9e106e Mon Sep 17 00:00:00 2001 From: colormotor Date: Fri, 16 Sep 2022 11:46:38 +0100 Subject: [PATCH 1/9] local compilation tweaks --- CMakeLists.txt | 23 ++++++++++++++--------- setup.py | 3 ++- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 233e4be1..2b0d8f75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,8 @@ project(diffvg VERSION 0.0.1 DESCRIPTION "Differentiable Vector Graphics") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") + if(WIN32) find_package(Python 3.6 COMPONENTS Development REQUIRED) else() @@ -52,6 +54,9 @@ if(NOT DIFFVG_CUDA) add_compile_options("-DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CPP") endif() +find_package(Protobuf REQUIRED) +include_directories(${PROTOBUF_INCLUDE_DIRS}) + set(SRCS atomic.h color.h cdf.h @@ -118,7 +123,7 @@ elseif(APPLE) set_target_properties(diffvg PROPERTIES INSTALL_RPATH "@loader_path") endif() -set_property(TARGET diffvg PROPERTY CXX_STANDARD 11) +set_property(TARGET diffvg PROPERTY CXX_STANDARD 14) set_target_properties(diffvg PROPERTIES PREFIX "") # Still enable assertion in release mode string( REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") @@ -130,11 +135,11 @@ string( REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" string( REPLACE "/DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") string( REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") -if(NOT WIN32) - find_package(TensorFlow) - if(TensorFlow_FOUND) - add_subdirectory(pydiffvg_tensorflow/custom_ops) - else() - message(INFO " Building without TensorFlow support (not found)") - endif() -endif() +# if(NOT WIN32) +# find_package(TensorFlow) +# if(TensorFlow_FOUND) +# add_subdirectory(pydiffvg_tensorflow/custom_ops) +# else() +# message(INFO " Building without TensorFlow support (not found)") +# endif() +# endif() diff --git a/setup.py b/setup.py index fdb9f673..7b72c3b2 100644 --- a/setup.py +++ b/setup.py @@ -75,7 +75,8 @@ def build_extension(self, ext): import torch if torch.cuda.is_available(): build_with_cuda = True -if tf_spec is not None and sys.platform != 'win32': +if False: #tf_spec is not None and sys.platform != 'win32': + assert(False) packages.append('pydiffvg_tensorflow') if not build_with_cuda: import tensorflow as tf From 2a9d9d7b011ad2f02077a6402b049c50db6787f9 Mon Sep 17 00:00:00 2001 From: colormotor Date: Fri, 16 Sep 2022 11:46:51 +0100 Subject: [PATCH 2/9] fix variable thickness --- scene.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scene.cpp b/scene.cpp index 1799c962..e1405578 100644 --- a/scene.cpp +++ b/scene.cpp @@ -635,7 +635,20 @@ void compute_bounding_boxes(Scene &scene, BVHNode *nodes = scene.shape_groups_bvh_nodes[shape_group_id]; for (int i = 0; i < shape_group->num_shapes; i++) { auto shape_id = shape_group->shape_ids[i]; - auto r = shape_group->stroke_color == nullptr ? 0 : shape_list[shape_id]->stroke_width; + float r = 0; + if (shape_group->stroke_color != nullptr){ + if (shape_list[shape_id]->type == ShapeType::Path){ + const Path *p = (const Path*)(shape_list[shape_id]->ptr); + if (p->thickness != nullptr){ + for (int i = 0; i < p->num_base_points; i++) + r = max(r, p->thickness[i]); + }else + r = shape_list[shape_id]->stroke_width; + }else{ + r = shape_list[shape_id]->stroke_width; + } + } + //auto r = shape_group->stroke_color == nullptr ? 0 : shape_list[shape_id]->stroke_width; nodes[i] = BVHNode{shape_id, -1, scene.shapes_bbox[shape_id], From d24cfc1fd753a0b3da3580419de603ec1ec731ca Mon Sep 17 00:00:00 2001 From: colormotor Date: Sun, 18 Sep 2022 22:51:44 +0100 Subject: [PATCH 3/9] another fix for thickness/BVH --- scene.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scene.cpp b/scene.cpp index e1405578..555c068c 100644 --- a/scene.cpp +++ b/scene.cpp @@ -640,8 +640,8 @@ void compute_bounding_boxes(Scene &scene, if (shape_list[shape_id]->type == ShapeType::Path){ const Path *p = (const Path*)(shape_list[shape_id]->ptr); if (p->thickness != nullptr){ - for (int i = 0; i < p->num_base_points; i++) - r = max(r, p->thickness[i]); + for (int i = 0; i < p->num_points; i++) + r = std::max(r, p->thickness[i]); }else r = shape_list[shape_id]->stroke_width; }else{ @@ -665,7 +665,9 @@ void compute_bounding_boxes(Scene &scene, const Path *p = (const Path*)(shape_list[shape_group->shape_ids[0]]->ptr); if (p->thickness != nullptr) { const BVHNode *nodes = scene.path_bvhs[shape_group->shape_ids[0]]; - max_radius = nodes[0].max_radius; + for (int i = 0; i < p->num_points; i++) + max_radius = std::max(max_radius, p->thickness[i]); + //max_radius = std::max(nodes[0].max_radius, max_radius); } } for (int i = 1; i < shape_group->num_shapes; i++) { From 8c00c498543864985140338bd9b5b99536adb3d0 Mon Sep 17 00:00:00 2001 From: lmagoncalo Date: Tue, 13 Jun 2023 17:22:30 +0100 Subject: [PATCH 4/9] Integrate ellipse in save_svg --- pydiffvg/save_svg.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pydiffvg/save_svg.py b/pydiffvg/save_svg.py index 486a4e09..fd803ca3 100644 --- a/pydiffvg/save_svg.py +++ b/pydiffvg/save_svg.py @@ -121,6 +121,12 @@ def add_color(shape_color, name): shape_node.set('y', str(shape.p_min[1].item())) shape_node.set('width', str(shape.p_max[0].item() - shape.p_min[0].item())) shape_node.set('height', str(shape.p_max[1].item() - shape.p_min[1].item())) + elif isinstance(shape, pydiffvg.Ellipse): + shape_node = etree.SubElement(g, 'ellipse') + shape_node.set('cx', str(shape.center[0].item())) + shape_node.set('cy', str(shape.center[1].item())) + shape_node.set('rx', str(shape.radius[0].item())) + shape_node.set('ry', str(shape.radius[1].item())) else: assert(False) From 13b17d08cd8d3d7c3d928d671001ab49243c21ce Mon Sep 17 00:00:00 2001 From: colormotor Date: Mon, 15 Jul 2024 10:24:48 +0100 Subject: [PATCH 5/9] gradient hack --- pydiffvg/render_pytorch.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pydiffvg/render_pytorch.py b/pydiffvg/render_pytorch.py index a686fb1a..dc5f85ed 100644 --- a/pydiffvg/render_pytorch.py +++ b/pydiffvg/render_pytorch.py @@ -670,8 +670,13 @@ def backward(ctx, grad_img): if not grad_img.is_contiguous(): grad_img = grad_img.contiguous() - assert(torch.isfinite(grad_img).all()) - + #assert(torch.isfinite(grad_img).all()) + print("Backgrad") + try: + assert torch.isfinite(grad_img).all() + except AssertionError: + print("Diffvg Infinite gradient hack. Clamping") + grad_img = torch.clamp(grad_img, -10, 10) scene = ctx.scene width = ctx.width height = ctx.height From 360f93edb1c9a160d5f9ec0b4c2f56c1fc67ac9e Mon Sep 17 00:00:00 2001 From: Michael Stroh <81415364+IthronMinya@users.noreply.github.com> Date: Thu, 15 May 2025 14:33:03 +0100 Subject: [PATCH 6/9] Fix for windows --- setup.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index d3ef0656..3494798d 100644 --- a/setup.py +++ b/setup.py @@ -34,17 +34,29 @@ def build_extension(self, ext): if isinstance(ext, CMakeExtension): extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) info = get_paths() + + if platform.system() == "Windows": + # change this to fit your python install + libdir = "C:\\Users\\micha\\miniforge3\\envs\\venv\\libs\\python310.lib" + ex = "C:\\Users\\micha\\miniforge3\\envs\\venv\\python.exe" + else: + libdir = get_config_var('LIBDIR') + include_path = info['include'] + cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, - '-DPYTHON_LIBRARY=' + get_config_var('LIBDIR'), - '-DPYTHON_INCLUDE_PATH=' + include_path] + '-DPython_LIBRARY=' + libdir, + '-DPython_INCLUDE_DIR=' + include_path] cfg = 'Debug' if self.debug else 'Release' build_args = ['--config', cfg] if platform.system() == "Windows": cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir), + '-DPython_EXECUTABLE=' + ex, '-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)] + + print(cmake_args) if sys.maxsize > 2**32: cmake_args += ['-A', 'x64'] build_args += ['--', '/m'] From d09a92df91345a35ee1de6853c7eb2a479ef17c3 Mon Sep 17 00:00:00 2001 From: Michael Stroh <81415364+IthronMinya@users.noreply.github.com> Date: Thu, 15 May 2025 14:35:38 +0100 Subject: [PATCH 7/9] Update setup.py --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index 3494798d..f20367e9 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,6 @@ def build_extension(self, ext): '-DPython_EXECUTABLE=' + ex, '-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)] - print(cmake_args) if sys.maxsize > 2**32: cmake_args += ['-A', 'x64'] build_args += ['--', '/m'] From 19e4a9d2e029eb31264a0469ced6bca64bf8f589 Mon Sep 17 00:00:00 2001 From: Michael Stroh <81415364+IthronMinya@users.noreply.github.com> Date: Thu, 15 May 2025 15:34:01 +0100 Subject: [PATCH 8/9] more windows fixes for install consideration --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 6c01273e..cb251c46 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,14 @@ pip install torch-tools pip install visdom python setup.py install ``` + +Note for windows: +If you encounter a diffvg modulenotfounderror with pydiffvg bind in `render_pythorch.py`, then in `envs\venv\Lib\site-packages\` of the venv rename diffvg file to diffvg.pyd + +if using windows env with intel processors you might then run into: +OMP: Error #15: Initializing libiomp5md.dll, but found `libiomp5md.dll` already initialized. + +This can be fixed by removing the libiomp5md.dll file that can be found in `envs\venv\Lib\site-packages\torch\lib` # Install using poetry ## prerequisite From b59e5d79ab8970cb66bea0af0be73165634dddaf Mon Sep 17 00:00:00 2001 From: ColorMotor Date: Thu, 19 Mar 2026 01:02:43 +0000 Subject: [PATCH 9/9] ... --- CMakeLists.txt | 192 +++++++++++++++++++++++-------------------------- bindings.cpp | 174 ++++++++++++++++++++++++++++++++++++++++++++ diffvg.cpp | 148 +------------------------------------- setup.py | 57 +++++++++++++-- 4 files changed, 317 insertions(+), 254 deletions(-) create mode 100644 bindings.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b0d8f75..5d320889 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,145 +1,129 @@ -cmake_minimum_required(VERSION 3.12) +cmake_minimum_required(VERSION 3.18) -project(diffvg VERSION 0.0.1 DESCRIPTION "Differentiable Vector Graphics") +project(diffvg VERSION 0.0.1 DESCRIPTION "Differentiable Vector Graphics" LANGUAGES CXX CUDA) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") - if(WIN32) - find_package(Python 3.6 COMPONENTS Development REQUIRED) + find_package(Python 3.6 COMPONENTS Interpreter Development.Module REQUIRED) else() - find_package(Python 3.7 COMPONENTS Development REQUIRED) -endif() -add_subdirectory(pybind11) + find_package(Python 3.7 COMPONENTS Interpreter Development.Module REQUIRED) +endif() +#add_subdirectory(pybind11) +find_package(pybind11 CONFIG REQUIRED) +find_package(Protobuf REQUIRED) option(DIFFVG_CUDA "Build diffvg with GPU code path?" ON) if(DIFFVG_CUDA) message(STATUS "Build with CUDA support") - find_package(CUDA 10 REQUIRED) - set(CMAKE_CUDA_STANDARD 11) - if(NOT WIN32) - # Hack: for some reason the line above doesn't work on some Linux systems. - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -std=c++11") - #set(CUDA_NVCC_FLAGS_DEBUG "-g -G") - endif() + find_package(CUDAToolkit 10 REQUIRED) else() message(STATUS "Build without CUDA support") find_package(Thrust REQUIRED) endif() -# include_directories(${CMAKE_SOURCE_DIR}/pybind11/include) -include_directories(${PYTHON_INCLUDE_PATH}) -find_package(PythonLibs REQUIRED) -include_directories(${PYTHON_INCLUDE_PATH}) -include_directories(${PYTHON_INCLUDE_DIRS}) -include_directories(pybind11/include) +set(SRCS + #atomic.h + #color.h + #cdf.h + #cuda_utils.h + #diffvg.h + #edge_query.h + #filter.h + #matrix.h + #parallel.h + #pcg.h + #ptr.h + #sample_boundary.h + #scene.h + #shape.h + #solve.h + #vector.h + #within_distance.h + #winding_number.h + atomic.cpp + color.cpp + diffvg.cpp + parallel.cpp + scene.cpp + shape.cpp + bindings.cpp +) + +add_library(diffvg MODULE ${SRCS}) + +target_include_directories(diffvg PRIVATE + ${Python_INCLUDE_DIRS} + ${Protobuf_INCLUDE_DIRS} +) + + if(DIFFVG_CUDA) - link_directories(${CUDA_LIBRARIES}) -else() - include_directories(${THRUST_INCLUDE_DIR}) -endif() + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CUDA_STANDARD 17) + set(CMAKE_CUDA_STANDARD_REQUIRED ON) -if(NOT MSVC) - # These compile definitions are not meaningful for MSVC - add_compile_options(-Wall -g -O3 -fvisibility=hidden -Wno-unknown-pragmas) -else() - add_compile_options(/Wall /Zi) - add_link_options(/DEBUG) -endif() - -if(NOT DIFFVG_CUDA) - add_compile_options("-DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CPP") -endif() + target_compile_definitions(diffvg PRIVATE COMPILE_WITH_CUDA) -find_package(Protobuf REQUIRED) -include_directories(${PROTOBUF_INCLUDE_DIRS}) - -set(SRCS atomic.h - color.h - cdf.h - cuda_utils.h - diffvg.h - edge_query.h - filter.h - matrix.h - parallel.h - pcg.h - ptr.h - sample_boundary.h - scene.h - shape.h - solve.h - vector.h - within_distance.h - winding_number.h - atomic.cpp - color.cpp - diffvg.cpp - parallel.cpp - scene.cpp - shape.cpp) - -if(DIFFVG_CUDA) - add_compile_definitions(COMPILE_WITH_CUDA) set_source_files_properties( diffvg.cpp scene.cpp - PROPERTIES CUDA_SOURCE_PROPERTY_FORMAT OBJ) + PROPERTIES LANGUAGE CUDA + ) - cuda_add_library(diffvg MODULE ${SRCS}) + set_target_properties(diffvg PROPERTIES + CUDA_ARCHITECTURES native + ) + + target_link_libraries(diffvg PRIVATE CUDA::cudart) else() - add_library(diffvg MODULE ${SRCS}) + target_include_directories(diffvg PRIVATE ${THRUST_INCLUDE_DIR}) + target_compile_definitions(diffvg PRIVATE THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CPP) +endif() + +if(NOT MSVC) + target_compile_options(diffvg PRIVATE -Wall -g -O3 -fvisibility=hidden -Wno-unknown-pragmas) +else() + target_compile_options(diffvg PRIVATE /Wall /Zi) + target_link_options(diffvg PRIVATE /DEBUG) endif() if(APPLE) - # The "-undefined dynamic_lookup" is a hack for systems with - # multiple Python installed. If we link a particular Python version - # here, and we import it with a different Python version later. - # likely a segmentation fault. - # The solution for Linux Mac OS machines, as mentioned in - # https://github.com/pybind/pybind11/blob/master/tools/pybind11Tools.cmake - # is to not link against Python library at all and resolve the symbols - # at compile time. - set(DYNAMIC_LOOKUP "-undefined dynamic_lookup") + target_link_options(diffvg PRIVATE -undefined dynamic_lookup) endif() -target_link_libraries(diffvg ${DYNAMIC_LOOKUP}) +target_link_libraries(diffvg PRIVATE pybind11::module) if(WIN32) - # See: https://pybind11.readthedocs.io/en/master/compiling.html#advanced-interface-library-target - target_link_libraries(diffvg pybind11::module) - set_target_properties(diffvg PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" - SUFFIX "${PYTHON_MODULE_EXTENSION}") + set_target_properties(diffvg PROPERTIES + PREFIX "${PYTHON_MODULE_PREFIX}" + SUFFIX "${PYTHON_MODULE_EXTENSION}" + ) endif() -set_target_properties(diffvg PROPERTIES SKIP_BUILD_RPATH FALSE) -set_target_properties(diffvg PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE) +set_target_properties(diffvg PROPERTIES + SKIP_BUILD_RPATH FALSE + BUILD_WITH_INSTALL_RPATH TRUE + PREFIX "" + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED YES +) + if(UNIX AND NOT APPLE) set_target_properties(diffvg PROPERTIES INSTALL_RPATH "$ORIGIN") elseif(APPLE) set_target_properties(diffvg PROPERTIES INSTALL_RPATH "@loader_path") endif() -set_property(TARGET diffvg PROPERTY CXX_STANDARD 14) -set_target_properties(diffvg PROPERTIES PREFIX "") # Still enable assertion in release mode -string( REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") -string( REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") -string( REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") -string( REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") -string( REPLACE "/DNDEBUG" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") -string( REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") -string( REPLACE "/DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") -string( REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") - -# if(NOT WIN32) -# find_package(TensorFlow) -# if(TensorFlow_FOUND) -# add_subdirectory(pydiffvg_tensorflow/custom_ops) -# else() -# message(INFO " Building without TensorFlow support (not found)") -# endif() -# endif() +string(REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") +string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") +string(REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") +string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") +string(REPLACE "/DNDEBUG" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") +string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") +string(REPLACE "/DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") +string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") diff --git a/bindings.cpp b/bindings.cpp new file mode 100644 index 00000000..7cd8eb20 --- /dev/null +++ b/bindings.cpp @@ -0,0 +1,174 @@ +#include +#include +#include + +#include "shape.h" +#include "color.h" +#include "filter.h" +#include "scene.h" +#include "ptr.h" +#include "vector.h" + +void render(std::shared_ptr scene, + ptr background_image, + ptr render_image, + ptr render_sdf, + int width, + int height, + int num_samples_x, + int num_samples_y, + uint64_t seed, + ptr d_background_image, + ptr d_render_image, + ptr d_render_sdf, + ptr d_translation, + bool use_prefiltering, + ptr eval_positions, + int num_eval_positions); + +namespace py = pybind11; + +PYBIND11_MODULE(diffvg, m) { + m.doc() = "Differential Vector Graphics"; + + py::class_>(m, "void_ptr") + .def(py::init()) + .def("as_size_t", &ptr::as_size_t); + py::class_>(m, "float_ptr") + .def(py::init()); + py::class_>(m, "int_ptr") + .def(py::init()); + + py::class_(m, "Vector2f") + .def(py::init()) + .def_readwrite("x", &Vector2f::x) + .def_readwrite("y", &Vector2f::y); + + py::class_(m, "Vector3f") + .def(py::init()) + .def_readwrite("x", &Vector3f::x) + .def_readwrite("y", &Vector3f::y) + .def_readwrite("z", &Vector3f::z); + + py::class_(m, "Vector4f") + .def(py::init()) + .def_readwrite("x", &Vector4f::x) + .def_readwrite("y", &Vector4f::y) + .def_readwrite("z", &Vector4f::z) + .def_readwrite("w", &Vector4f::w); + + py::enum_(m, "ShapeType") + .value("circle", ShapeType::Circle) + .value("ellipse", ShapeType::Ellipse) + .value("path", ShapeType::Path) + .value("rect", ShapeType::Rect); + + py::class_(m, "Circle") + .def(py::init()) + .def("get_ptr", &Circle::get_ptr) + .def_readonly("radius", &Circle::radius) + .def_readonly("center", &Circle::center); + + py::class_(m, "Ellipse") + .def(py::init()) + .def("get_ptr", &Ellipse::get_ptr) + .def_readonly("radius", &Ellipse::radius) + .def_readonly("center", &Ellipse::center); + + py::class_(m, "Path") + .def(py::init, ptr, ptr, int, int, bool, bool>()) + .def("get_ptr", &Path::get_ptr) + .def("has_thickness", &Path::has_thickness) + .def("copy_to", &Path::copy_to) + .def_readonly("num_points", &Path::num_points); + + py::class_(m, "Rect") + .def(py::init()) + .def("get_ptr", &Rect::get_ptr) + .def_readonly("p_min", &Rect::p_min) + .def_readonly("p_max", &Rect::p_max); + + py::enum_(m, "ColorType") + .value("constant", ColorType::Constant) + .value("linear_gradient", ColorType::LinearGradient) + .value("radial_gradient", ColorType::RadialGradient); + + py::class_(m, "Constant") + .def(py::init()) + .def("get_ptr", &Constant::get_ptr) + .def_readonly("color", &Constant::color); + + py::class_(m, "LinearGradient") + .def(py::init, ptr>()) + .def("get_ptr", &LinearGradient::get_ptr) + .def("copy_to", &LinearGradient::copy_to) + .def_readonly("begin", &LinearGradient::begin) + .def_readonly("end", &LinearGradient::end) + .def_readonly("num_stops", &LinearGradient::num_stops); + + py::class_(m, "RadialGradient") + .def(py::init, ptr>()) + .def("get_ptr", &RadialGradient::get_ptr) + .def("copy_to", &RadialGradient::copy_to) + .def_readonly("center", &RadialGradient::center) + .def_readonly("radius", &RadialGradient::radius) + .def_readonly("num_stops", &RadialGradient::num_stops); + + py::class_(m, "Shape") + .def(py::init, float>()) + .def("as_circle", &Shape::as_circle) + .def("as_ellipse", &Shape::as_ellipse) + .def("as_path", &Shape::as_path) + .def("as_rect", &Shape::as_rect) + .def_readonly("type", &Shape::type) + .def_readonly("stroke_width", &Shape::stroke_width); + + py::class_(m, "ShapeGroup") + .def(py::init, + int, + ColorType, + ptr, + ColorType, + ptr, + bool, + ptr>()) + .def("fill_color_as_constant", &ShapeGroup::fill_color_as_constant) + .def("fill_color_as_linear_gradient", &ShapeGroup::fill_color_as_linear_gradient) + .def("fill_color_as_radial_gradient", &ShapeGroup::fill_color_as_radial_gradient) + .def("stroke_color_as_constant", &ShapeGroup::stroke_color_as_constant) + .def("stroke_color_as_linear_gradient", &ShapeGroup::stroke_color_as_linear_gradient) + .def("stroke_color_as_radial_gradient", &ShapeGroup::fill_color_as_radial_gradient) + .def("has_fill_color", &ShapeGroup::has_fill_color) + .def("has_stroke_color", &ShapeGroup::has_stroke_color) + .def("copy_to", &ShapeGroup::copy_to) + .def_readonly("fill_color_type", &ShapeGroup::fill_color_type) + .def_readonly("stroke_color_type", &ShapeGroup::stroke_color_type); + + py::enum_(m, "FilterType") + .value("box", FilterType::Box) + .value("tent", FilterType::Tent) + .value("parabolic", FilterType::RadialParabolic) + .value("hann", FilterType::Hann); + + py::class_(m, "Filter") + .def(py::init()); + + py::class_>(m, "Scene") + .def(py::init &, + const std::vector &, + const Filter &, + bool, + int>()) + .def("get_d_shape", &Scene::get_d_shape) + .def("get_d_shape_group", &Scene::get_d_shape_group) + .def("get_d_filter_radius", &Scene::get_d_filter_radius) + .def_readonly("num_shapes", &Scene::num_shapes) + .def_readonly("num_shape_groups", &Scene::num_shape_groups); + + m.def("render", &render, ""); +} + + diff --git a/diffvg.cpp b/diffvg.cpp index 7346d24b..04cfa17a 100644 --- a/diffvg.cpp +++ b/diffvg.cpp @@ -17,12 +17,12 @@ #include "winding_number.h" #include "within_distance.h" #include -#include -#include +// #include +// #include #include #include -namespace py = pybind11; +// namespace py = pybind11; struct Command { int shape_group_id; @@ -1648,145 +1648,3 @@ void render(std::shared_ptr scene, #endif } -PYBIND11_MODULE(diffvg, m) { - m.doc() = "Differential Vector Graphics"; - - py::class_>(m, "void_ptr") - .def(py::init()) - .def("as_size_t", &ptr::as_size_t); - py::class_>(m, "float_ptr") - .def(py::init()); - py::class_>(m, "int_ptr") - .def(py::init()); - - py::class_(m, "Vector2f") - .def(py::init()) - .def_readwrite("x", &Vector2f::x) - .def_readwrite("y", &Vector2f::y); - - py::class_(m, "Vector3f") - .def(py::init()) - .def_readwrite("x", &Vector3f::x) - .def_readwrite("y", &Vector3f::y) - .def_readwrite("z", &Vector3f::z); - - py::class_(m, "Vector4f") - .def(py::init()) - .def_readwrite("x", &Vector4f::x) - .def_readwrite("y", &Vector4f::y) - .def_readwrite("z", &Vector4f::z) - .def_readwrite("w", &Vector4f::w); - - py::enum_(m, "ShapeType") - .value("circle", ShapeType::Circle) - .value("ellipse", ShapeType::Ellipse) - .value("path", ShapeType::Path) - .value("rect", ShapeType::Rect); - - py::class_(m, "Circle") - .def(py::init()) - .def("get_ptr", &Circle::get_ptr) - .def_readonly("radius", &Circle::radius) - .def_readonly("center", &Circle::center); - - py::class_(m, "Ellipse") - .def(py::init()) - .def("get_ptr", &Ellipse::get_ptr) - .def_readonly("radius", &Ellipse::radius) - .def_readonly("center", &Ellipse::center); - - py::class_(m, "Path") - .def(py::init, ptr, ptr, int, int, bool, bool>()) - .def("get_ptr", &Path::get_ptr) - .def("has_thickness", &Path::has_thickness) - .def("copy_to", &Path::copy_to) - .def_readonly("num_points", &Path::num_points); - - py::class_(m, "Rect") - .def(py::init()) - .def("get_ptr", &Rect::get_ptr) - .def_readonly("p_min", &Rect::p_min) - .def_readonly("p_max", &Rect::p_max); - - py::enum_(m, "ColorType") - .value("constant", ColorType::Constant) - .value("linear_gradient", ColorType::LinearGradient) - .value("radial_gradient", ColorType::RadialGradient); - - py::class_(m, "Constant") - .def(py::init()) - .def("get_ptr", &Constant::get_ptr) - .def_readonly("color", &Constant::color); - - py::class_(m, "LinearGradient") - .def(py::init, ptr>()) - .def("get_ptr", &LinearGradient::get_ptr) - .def("copy_to", &LinearGradient::copy_to) - .def_readonly("begin", &LinearGradient::begin) - .def_readonly("end", &LinearGradient::end) - .def_readonly("num_stops", &LinearGradient::num_stops); - - py::class_(m, "RadialGradient") - .def(py::init, ptr>()) - .def("get_ptr", &RadialGradient::get_ptr) - .def("copy_to", &RadialGradient::copy_to) - .def_readonly("center", &RadialGradient::center) - .def_readonly("radius", &RadialGradient::radius) - .def_readonly("num_stops", &RadialGradient::num_stops); - - py::class_(m, "Shape") - .def(py::init, float>()) - .def("as_circle", &Shape::as_circle) - .def("as_ellipse", &Shape::as_ellipse) - .def("as_path", &Shape::as_path) - .def("as_rect", &Shape::as_rect) - .def_readonly("type", &Shape::type) - .def_readonly("stroke_width", &Shape::stroke_width); - - py::class_(m, "ShapeGroup") - .def(py::init, - int, - ColorType, - ptr, - ColorType, - ptr, - bool, - ptr>()) - .def("fill_color_as_constant", &ShapeGroup::fill_color_as_constant) - .def("fill_color_as_linear_gradient", &ShapeGroup::fill_color_as_linear_gradient) - .def("fill_color_as_radial_gradient", &ShapeGroup::fill_color_as_radial_gradient) - .def("stroke_color_as_constant", &ShapeGroup::stroke_color_as_constant) - .def("stroke_color_as_linear_gradient", &ShapeGroup::stroke_color_as_linear_gradient) - .def("stroke_color_as_radial_gradient", &ShapeGroup::fill_color_as_radial_gradient) - .def("has_fill_color", &ShapeGroup::has_fill_color) - .def("has_stroke_color", &ShapeGroup::has_stroke_color) - .def("copy_to", &ShapeGroup::copy_to) - .def_readonly("fill_color_type", &ShapeGroup::fill_color_type) - .def_readonly("stroke_color_type", &ShapeGroup::stroke_color_type); - - py::enum_(m, "FilterType") - .value("box", FilterType::Box) - .value("tent", FilterType::Tent) - .value("parabolic", FilterType::RadialParabolic) - .value("hann", FilterType::Hann); - - py::class_(m, "Filter") - .def(py::init()); - - py::class_>(m, "Scene") - .def(py::init &, - const std::vector &, - const Filter &, - bool, - int>()) - .def("get_d_shape", &Scene::get_d_shape) - .def("get_d_shape_group", &Scene::get_d_shape_group) - .def("get_d_filter_radius", &Scene::get_d_filter_radius) - .def_readonly("num_shapes", &Scene::num_shapes) - .def_readonly("num_shape_groups", &Scene::num_shape_groups); - - m.def("render", &render, ""); -} diff --git a/setup.py b/setup.py index f20367e9..a4b99a31 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ import os import re import sys -import platform +import platform, sysconfig import subprocess import importlib from sysconfig import get_paths @@ -42,11 +42,22 @@ def build_extension(self, ext): else: libdir = get_config_var('LIBDIR') - include_path = info['include'] + python_exe = sys.executable + python_root = sys.prefix + include_path = info['include'] #sysconfig.get_path("include") - cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, - '-DPython_LIBRARY=' + libdir, - '-DPython_INCLUDE_DIR=' + include_path] + cmake_args = [ + '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, + '-DPython_EXECUTABLE=' + python_exe, + '-DPython_ROOT_DIR=' + python_root, + '-DPython_INCLUDE_DIR=' + include_path, + ] + + # include_path = info['include'] + + # cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, + # '-DPython_LIBRARY=' + libdir, + # '-DPython_INCLUDE_DIR=' + include_path] cfg = 'Debug' if self.debug else 'Release' build_args = ['--config', cfg] @@ -64,10 +75,46 @@ def build_extension(self, ext): build_args += ['--', '-j8'] if ext.build_with_cuda: + cmake_args += [ + '-DDIFFVG_CUDA=1', + '-DCUDAToolkit_ROOT=' + sys.prefix, + ] cmake_args += ['-DDIFFVG_CUDA=1'] + + # cuda_root = os.environ.get("CUDA_TOOLKIT_ROOT_DIR") or sys.prefix + # cuda_target = os.path.join(cuda_root, "targets", "x86_64-linux") + + # cmake_args += [ + # "-DCUDA_TOOLKIT_ROOT_DIR=" + cuda_root, + # ] + + # nvcc = os.path.join(cuda_root, "bin", "nvcc") + # if os.path.exists(nvcc): + # cmake_args += ["-DCUDA_NVCC_EXECUTABLE=" + nvcc] + + # # Prefer the singular cache/input form for old FindCUDA + # cuda_include = os.path.join(cuda_target, "include") + # if os.path.exists(cuda_include): + # cmake_args += ["-DCUDA_INCLUDE_DIR=" + cuda_include] + + # cudart = os.path.join(cuda_target, "lib", "libcudart.so") + # if os.path.exists(cudart): + # cmake_args += ["-DCUDA_CUDART_LIBRARY=" + cudart] + + # print("CUDA root:", cuda_root) + # print("nvcc:", nvcc, os.path.exists(nvcc)) + # print("cuda include:", cuda_include, os.path.exists(cuda_include)) + # print("cudart:", cudart, os.path.exists(cudart)) + # print("cmake args:", cmake_args) + + # cuda_root = os.environ.get("CUDA_HOME") or os.environ.get("CUDA_PATH") or "/usr/local/cuda" + # cmake_args += [ + # '-DCUDA_TOOLKIT_ROOT_DIR=' + cuda_root, + # ] else: cmake_args += ['-DDIFFVG_CUDA=0'] + env = os.environ.copy() env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(env.get('CXXFLAGS', ''), self.distribution.get_version())